home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1994-09-17 | 154.4 KB | 5,116 lines | [ TEXT/MPS ]
/* * This file has been changed from the original MacApp 3.1.1 * to support the metrowerks CodeWarrior compilers C/C++ 1.1.1. * These changes are known *not* to work with earlier versions * of CodeWarrior. Every attempt though has been made to to keep * this file compatible with other development environments. * * Mark Anderson * metrowerks * 9/16/94 * */ //---------------------------------------------------------------------------------------- // UApplication.cp // Copyright © 1984-1994 by Apple Computer Inc. All rights reserved. //---------------------------------------------------------------------------------------- #ifndef __UAPPLICATION__ #include <UApplication.h> #endif #ifndef __STDIO__ #include <stdio.h> #endif #ifndef __UGEOMETRY__ #include <UGeometry.h> #endif #ifndef __UBEHAVIOR__ #include <UBehavior.h> #endif #ifndef __UFILE__ #include <UFile.h> #endif #ifndef __UAPPLEEVENTS__ #include <UAppleEvents.h> #endif #ifndef __UPRINTHANDLER__ #include <UPrintHandler.h> #endif #ifndef __UWINDOW__ #include <UWindow.h> #endif #ifndef __USCROLLER__ #include <UScroller.h> #endif #ifndef __UDOCUMENT__ #include <UDocument.h> #endif #ifndef __UMACAPPUTILITIES__ #include <UMacAppUtilities.h> #endif #ifndef __UERRORMGR__ #include <UErrorMgr.h> #endif #ifndef __UMEMORY__ #include <UMemory.h> #endif #ifndef __UMENUMGR__ #include <UMenuMgr.h> #endif #ifndef __UMACAPPGLOBALS__ #include <UMacAppGlobals.h> #endif #ifndef __UDEPENDENCIES__ #include "UDependencies.h" #endif #ifndef __ERRORS__ #include <Errors.h> #endif #ifndef __TOOLUTILS__ #include <ToolUtils.h> #endif #ifndef __UBUSYCURSOR__ #include <UBusyCursor.h> #endif #ifndef __UDEBUG__ #include <UDebug.h> #endif #ifndef __UCLIPBOARDMGR__ #include <UClipboardMgr.h> #endif #ifndef __RESOURCES__ #include <Resources.h> #endif #ifndef __DESK__ #include <Desk.h> #endif #ifndef __PACKAGES__ #include <Packages.h> #endif #ifndef __SCRIPT__ #include <Script.h> #endif #ifndef __DISKINIT__ #include <DiskInit.h> #endif #ifndef __OSEVENTS__ #include <OSEvents.h> #endif #ifndef __ULOMEM__ #include <ULoMem.h> #endif #ifndef __STDLIB__ #include <stdlib.h> #endif #ifndef __UVIEWSERVER__ #include <UViewServer.h> #endif #ifndef __UTABBEHAVIORS__ #include <UTabBehaviors.h> #endif #ifndef __UPRINTING__ #include <UPrinting.h> #endif #ifndef __GESTALTEQU__ #include <GestaltEqu.h> #endif #ifndef __LOWMEM__ #include <LowMem.h> #endif #ifndef __DEVICES__ #include <Devices.h> #endif #if qNeedsVU #ifndef __UVUASSIST__ #include <UVUAssist.h> #endif #endif //---------------------------------------------------------------------------------------- // Constant definitions //---------------------------------------------------------------------------------------- enum SystemJustification { smSysJustLeft = 0, smSysJustRight = -1 }; // Constants to use with GetSysDirection() and SetSysDirection(). //---------------------------------------------------------------------------------------- // Global variable definitions. //---------------------------------------------------------------------------------------- TApplication* gApplication = NULL; Boolean gInitialized = false; AEAddressDesc gServerAddress; Boolean hadCreditsStringList; // does the rsrc 'STR#' == kDefaultCredits exist ? short lastCreditsStringIndex; // the last CString in the STR# to be displayed long lastCreditsShownTicks; // the tickcount when the last Credit was Shown CStringHandle originalText; // the about box's original text (prior to credits) short waitTicks; // how long to wait between credits //======================================================================================== // GLOBAL Procedures //======================================================================================== #undef Inherited //---------------------------------------------------------------------------------------- // DoShowAboutAppFilter: //---------------------------------------------------------------------------------------- #pragma segment MAAboutApp pascal Boolean DoShowAboutAppFilter(DialogPtr theDialog, EventRecord& theEvent, short& itemHit) { CStr255 s; CStr255 originalStr; Handle item; Boolean returnValue = false; short itemType; CRect box; switch (theEvent.what) { case keyDown: switch ((unsigned char)(((theEvent.message) & charCodeMask))) { case chEnter: case chReturn: DoAlertKeyDown(theDialog, ok); break; } break; case nullEvent: if ((TickCount() - lastCreditsShownTicks) > waitTicks) { short itemNo = 1; do { item = NULL; GetDialogItem(theDialog, itemNo, &itemType, &item, box); if (((itemType) & 0x7F) == statText)// we don't care if its enabled or not break; else ++itemNo; } while (item); GetIndString(s, kDefaultCredits, lastCreditsStringIndex); if (!s.IsEmpty()) { // save the original text if ((lastCreditsStringIndex == 1) && ((*originalText)->IsEmpty() && item)) { GetDialogItemText(item, originalStr); SetString((StringHandle)originalText, (ConstStr255Param)&originalStr); } ++lastCreditsStringIndex; lastCreditsShownTicks = TickCount(); if (item) SetDialogItemText(item, s); waitTicks = (short)Min((s.Length() * 6), 60); } else // no more items { lastCreditsStringIndex = 1; lastCreditsShownTicks = TickCount(); if (item) { BlockMove((*originalText), &originalStr, (**originalText).Length() + 1); SetDialogItemText(item, originalStr); } waitTicks = 6 * 60; } } break; } /* switch */ // Forward on to the standard filter if (gMacAppAlertFilter) returnValue = ((ModalFilterProcPtr)gMacAppAlertFilter)(theDialog, &theEvent, &itemHit); return returnValue; } // DoShowAboutAppFilter #if !qPowerPC //---------------------------------------------------------------------------------------- // IsOpen: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand typedef DCtlHandle UnitTable[129]; typedef UnitTable* UnitTablePtr; Boolean IsOpen(short itsID) { DCtlHandle dceHnd; if ((itsID >= 0) && (itsID < GetUnitEntryCount())) { dceHnd = (*((UnitTablePtr)LMGetUTableBase()))[itsID]; return ((dceHnd) && ((((*dceHnd)->dCtlFlags) & 0x0400) != 0)); } else return false; } // IsOpen #endif //======================================================================================== // CLASS CEventListIterator //======================================================================================== #undef Inherited #pragma segment MAApplicationRes class CEventListIterator : public CIterator { public: // These items are currently public for searching ArrayIndex fCurrentIndex; // current index of this iteration protected: TEventList *fEventList; // the main event list public: CEventListIterator(TEventList* itsEventList); virtual Boolean More(); // override // Returns true if there are more elements to iterate over TEvent* FirstEvent(); // Resets the iterator to begin again and returns the value of the first index in // the iteration TEvent* NextEvent(); // Advances the iteration and then returns the index protected: virtual void Advance(); // override // Advances the iteration }; //---------------------------------------------------------------------------------------- // CEventListIterator::CEventListIterator: //---------------------------------------------------------------------------------------- inline CEventListIterator::CEventListIterator(TEventList* itsEventList) { fEventList = itsEventList; fCurrentIndex = itsEventList->GetSize(); // We iterate backward over the event list } // CEventListIterator::CEventListIterator //---------------------------------------------------------------------------------------- // CEventListIterator::FirstEvent: //---------------------------------------------------------------------------------------- inline TEvent* CEventListIterator::FirstEvent() { if (this->More()) return (TEvent*)fEventList->At(fCurrentIndex); else return NULL; } // CEventListIterator::FirstEvent //---------------------------------------------------------------------------------------- // CEventListIterator::NextEvent: //---------------------------------------------------------------------------------------- inline TEvent* CEventListIterator::NextEvent() { this->Advance(); if (this->More()) return (TEvent*)fEventList->At(fCurrentIndex); else return NULL; } // CEventListIterator::NextEvent //---------------------------------------------------------------------------------------- // CEventListIterator::Advance: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void CEventListIterator::Advance() { if (fCurrentIndex > 1) --fCurrentIndex; else fCurrentIndex = kEmptyIndex; } // CEventListIterator::Advance //---------------------------------------------------------------------------------------- // CEventListIterator::More: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean CEventListIterator::More() { return (fCurrentIndex != kEmptyIndex); } // CEventListIterator::More //======================================================================================== // CLASS CDocumentIterator //======================================================================================== #undef Inherited //---------------------------------------------------------------------------------------- // CDocumentIterator::CDocumentIterator: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes CDocumentIterator::CDocumentIterator(TApplication* itsApplication, ArrayIndex itsLowBound, ArrayIndex itsHighBound, Boolean itsForward) : CObjectIterator(itsApplication ? itsApplication->fDocumentList : NULL, itsLowBound, itsHighBound, itsForward) { } // CDocumentIterator::CDocumentIterator //---------------------------------------------------------------------------------------- // CDocumentIterator::CDocumentIterator: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes CDocumentIterator::CDocumentIterator(TApplication* itsApplication, Boolean itsForward) : CObjectIterator(itsApplication ? itsApplication->fDocumentList : NULL, itsForward) { } // CDocumentIterator::CDocumentIterator //---------------------------------------------------------------------------------------- // CDocumentIterator::CDocumentIterator: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes CDocumentIterator::CDocumentIterator(TApplication* itsApplication) : CObjectIterator(itsApplication ? itsApplication->fDocumentList : NULL) { } // CDocumentIterator::CDocumentIterator //---------------------------------------------------------------------------------------- // CDocumentIterator::~CDocumentIterator: //---------------------------------------------------------------------------------------- #pragma segment IteratorRes CDocumentIterator::~CDocumentIterator() { } // CDocumentIterator::~CDocumentIterator //---------------------------------------------------------------------------------------- // CDocumentIterator::CurrentDocument: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TDocument* CDocumentIterator::CurrentDocument() { return (TDocument *)this->CurrentObject(); } // CDocumentIterator::CurrentDocument //---------------------------------------------------------------------------------------- // CDocumentIterator::FirstDocument: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TDocument* CDocumentIterator::FirstDocument() { return (TDocument *)this->FirstObject(); } // CDocumentIterator::FirstDocument //---------------------------------------------------------------------------------------- // CDocumentIterator::NextDocument: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TDocument* CDocumentIterator::NextDocument() { return (TDocument *)this->NextObject(); } // CDocumentIterator::NextDocument //======================================================================================== // struct CSetupTheMenus //======================================================================================== struct CSetupTheMenus { public: TApplication* fApplication; // Constructor CSetupTheMenus(TApplication* theApplication) : fApplication(theApplication) { } }; //---------------------------------------------------------------------------------------- // DoSetupTheMenus: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void DoSetupTheMenus(void* /* staticLink */) { // Set the Undo menu to "Can't Undo" before giving the target chain a chance // to change it. gApplication->SetUndoText(kShowCantUndo, cCantUndo); gClipboardMgr->fGotClipType = false; // so CanPaste will work correctly gApplication->GetTarget()->HandleSetupMenus();// Setup menus relevant to target chain // Set up the menu commands that are not dependent on the target chain… if (gApplication->fSysWindowActive) { Enable(cUndo, true); Enable(cCut, true); Enable(cCopy, true); Enable(cPaste, true); Enable(cClear, true); gApplication->SetUndoText(kShowUndo, cNoCommand); } #if qDebug { TWindow * aWindow = gApplication->GetActiveWindow(kNoFloaters); Enable(cRefreshFrontWindow, (aWindow != NULL)); Enable(cDoFirstClick, (aWindow != NULL)); if (aWindow) SetMenuState(cDoFirstClick, kDebugBuzzStrings, bzDoFirstClick, bzDontDoFirstClick, aWindow->fDoFirstClick); Enable(cDebugFlags, true); // System Justification - see comment in Debug.r // Enable(cSetSysJust, true); // SetMenuState(cSetSysJust, kDebugBuzzStrings, bzSetRightSysJust, bzSetLeftSysJust, GetSysDirection() != smSysJustLeft); } #endif #if qPerform { Boolean initiated = PerfMonitorInitiated(); Enable(cPerfMonInit, !initiated); Enable(cPerfMonDump, initiated); Enable(cPerfMonToggle, initiated); SetMenuState(cPerfMonToggle, kDebugBuzzStrings, bzContinuePerfMon, bzPausePerfMon, PerfMonitorEnabled()); Enable(cPerfMonEnd, initiated); } #endif MenuHandle appleMenu = MAGetMenuHandle(mApple); if (appleMenu != 0) { if (((*appleMenu)->enableFlags & 1) == gApplication->InModalState()) { (*appleMenu)->enableFlags = ((*appleMenu)->enableFlags ^ 1); InvalidateMenuBar(); } } } // DoSetupTheMenus //======================================================================================== // CLASS TEventList: Empty constructor to satisfy the compiler. //======================================================================================== #undef Inherited #define Inherited TSortedList #pragma segment MAInit DefineClass(TEventList, Inherited); //---------------------------------------------------------------------------------------- // TEventList::TEventList: Empty constructor to satisfy the compiler. //---------------------------------------------------------------------------------------- #pragma segment ConstructorRes TEventList::TEventList() { } // TEventList::TEventList //---------------------------------------------------------------------------------------- // TEventList::Compare: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes CompareResult TEventList::Compare(TObject* item1, TObject* item2) { // We want higher priority events at the end of the queue so we can delete from the // end of the list. This will save us a block move in DeleteElementsAt. if (((TEvent *)item1)->fPriority > ((TEvent *)item2)->fPriority) return kItem1LessThanItem2; else if (((TEvent *)item1)->fPriority < ((TEvent *)item2)->fPriority) return kItem1GreaterThanItem2; else return kItem1EqualItem2; } // TEventList::Compare //---------------------------------------------------------------------------------------- // TEventList::IEventList: //---------------------------------------------------------------------------------------- #pragma segment MAInit void TEventList::IEventList() { this->ISortedList(); } // TEventList::IEventList //---------------------------------------------------------------------------------------- // TEventList::Insert: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TEventList::Insert(TObject* item) // override { // Guarantee that the insertion can take place. Use AllocateObjectsFromPerm rather // than PermAllocation because TDynamicArray calls TObject::SetDynamicSize to change // the size of the array. TObject::SetDynamicSize checks the object allocation flag to // decide whether to use temporary or permanent memory for the resize. Boolean oldObjectPerm = AllocateObjectsFromPerm(false); VOLATILE(oldObjectPerm); FailInfo fi; Try(fi) { Inherited::Insert(item); fi.Success(); } else { AllocateObjectsFromPerm(oldObjectPerm); fi.ReSignal(); } AllocateObjectsFromPerm(oldObjectPerm); } // TEventList::Insert //======================================================================================== // CLASS TQuitCommand //======================================================================================== #undef Inherited #define Inherited TCommand #pragma segment MAApplicationRes DefineClass(TQuitCommand, Inherited); //---------------------------------------------------------------------------------------- // TQuitCommand: Empty constructor to satisfy the compiler. //---------------------------------------------------------------------------------------- #pragma segment ConstructorRes TQuitCommand::TQuitCommand() { } // TQuitCommand::TQuitCommand //---------------------------------------------------------------------------------------- // TQuitCommand::DoIt: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TQuitCommand::DoIt() { FailInfo fi; Try(fi) { gApplication->fDone = true; gApplication->Close(); fi.Success(); } else // Recover { gApplication->fDone = false; fi.ReSignal(); } } // TQuitCommand::DoIt //---------------------------------------------------------------------------------------- // TQuitCommand::IQuitCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TQuitCommand::IQuitCommand(CommandNumber itsCommandNumber) { this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL); } // TQuitCommand::IQuitCommand //---------------------------------------------------------------------------------------- // TQuitCommand::IsReadyToExecute: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TQuitCommand::IsReadyToExecute() // Override { // Don't execute Quit if application has a dialog posed modally! if (gApplication->InModalState()) return false; else return fReadyToExecute; } //======================================================================================== // CLASS TNewDocumentCommand //======================================================================================== #undef Inherited #define Inherited TCommand #pragma segment MAOpen DefineClass(TNewDocumentCommand, Inherited); //---------------------------------------------------------------------------------------- // TNewDocumentCommand: Empty constructor to satisfy the compiler. //---------------------------------------------------------------------------------------- #pragma segment ConstructorRes TNewDocumentCommand::TNewDocumentCommand() { } // TNewDocumentCommand::TNewDocumentCommand //---------------------------------------------------------------------------------------- // TNewDocumentCommand::DoIt: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TNewDocumentCommand::DoIt() { gApplication->OpenNew(fIdentifier); } // TNewDocumentCommand::DoIt //---------------------------------------------------------------------------------------- // TNewDocumentCommand::INewDocumentCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TNewDocumentCommand::INewDocumentCommand(CommandNumber itsCommandNumber) { this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL); } // TNewDocumentCommand::INewDocumentCommand //======================================================================================== // CLASS TFilesCommand //======================================================================================== #undef Inherited #define Inherited TServerCommand #pragma segment MASelCommand DefineClass(TFilesCommand, Inherited); //---------------------------------------------------------------------------------------- // TFilesCommand constructor //---------------------------------------------------------------------------------------- #pragma segment MASelCommand TFilesCommand::TFilesCommand() { fCausesChange = false; fFileList = NULL; } // TFilesCommand::TFilesCommand //---------------------------------------------------------------------------------------- // TFilesCommand::IFilesCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TFilesCommand::IFilesCommand(CommandNumber itsCommandNumber, TList* theDocuments) { this->IServerCommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL); fFileList = theDocuments; } // TFilesCommand::IFilesCommand //---------------------------------------------------------------------------------------- // TFilesCommand::InitializeFromAppleEvent: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TFilesCommand::InitializeFromAppleEvent(CommandNumber itsCommandNumber, TCommandHandler* itsContext, Boolean canUndo, Boolean causesChange, TObject* objectToNotify, const AppleEvent& itsMessage, const AppleEvent& itsReply) // override { Inherited::InitializeFromAppleEvent(itsCommandNumber, itsContext, canUndo, causesChange, objectToNotify, itsMessage, itsReply); THandleList * aHandleList = NULL; TList * aFileList = NULL; VOLATILE(aHandleList); VOLATILE(aFileList); FailInfo outerFi; Try(outerFi) { aHandleList = new THandleList; aHandleList->IHandleList(); FailInfo innerfi; Try(innerfi) { aFileList = NewList(); fMessage->ReadHandleList(keyDirectObject, typeAlias, aHandleList); // Block is necessary for correct failure handling { CHandleIterator iter(aHandleList); for (Handle item = iter.FirstHandle(); iter.More(); item = iter.NextHandle()) { TFile* aFile = NULL; VOLATILE(aFile); aFile = gApplication->DoMakeFile(itsCommandNumber); FailInfo onemorefi; Try(onemorefi) { FailOSErr(aFile->SpecifyWithAlias(AliasHandle(item))); aFileList->InsertLast(aFile); onemorefi.Success(); } else { aFile = (TFile*)FreeIfObject(aFile); onemorefi.ReSignal(); } aHandleList->Delete(item); // Delete it from the list so if we fail // we don't try to free it twice item = DisposeIfHandle(item); } } innerfi.Success(); } else // Recover { if (aHandleList) aHandleList->FreeList(); if (aFileList) aFileList->FreeList(); innerfi.ReSignal(); } outerFi.Success(); } else { this->Free(); outerFi.ReSignal(); } aHandleList->Free(); // It is just a list of disposed handles… fFileList = aFileList; } // TFilesCommand::InitializeFromAppleEvent //---------------------------------------------------------------------------------------- // TFilesCommand::Free: //---------------------------------------------------------------------------------------- #pragma segment MAClose void TFilesCommand::Free() // override { fFileList = (TList*)FreeListIfObject(fFileList); Inherited::Free(); } // TFilesCommand::Free //======================================================================================== // CLASS TODocCommand //======================================================================================== #undef Inherited #define Inherited TFilesCommand #pragma segment MASelCommand DefineClass(TODocCommand, Inherited); //---------------------------------------------------------------------------------------- // TODocCommand: Empty constructor to satisfy the compiler. //---------------------------------------------------------------------------------------- #pragma segment ConstructorRes TODocCommand::TODocCommand() { } // TODocCommand::TODocCommand //---------------------------------------------------------------------------------------- // TODocCommand::IODocCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TODocCommand::IODocCommand(CommandNumber itsCommandNumber, TList* theDocuments) { this->IFilesCommand(itsCommandNumber, theDocuments); } // TODocCommand::IODocCommand //---------------------------------------------------------------------------------------- // TODocCommand::DoIt: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TODocCommand::DoIt() // override { FailInfo fi; Try(fi) { gApplication->OpenOld(fIdentifier, fFileList); fi.Success(); } else { this->ReportError(fi.error, fi.message); fi.ReSignal(); } } // TODocCommand::DoIt //======================================================================================== // CLASS TPDocCommand //======================================================================================== #undef Inherited #define Inherited TFilesCommand #pragma segment MASelCommand DefineClass(TPDocCommand, Inherited); //---------------------------------------------------------------------------------------- // TPDocCommand constructor //---------------------------------------------------------------------------------------- #pragma segment MASelCommand TPDocCommand::TPDocCommand() { fRequiresUserInteraction = true; } // TPDocCommand::TPDocCommand //---------------------------------------------------------------------------------------- // TPDocCommand::IPDocCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TPDocCommand::IPDocCommand(CommandNumber itsCommandNumber, TList* theDocuments) { this->IFilesCommand(itsCommandNumber, theDocuments); } // TPDocCommand::IPDocCommand //---------------------------------------------------------------------------------------- // TPDocCommand::DoIt: //---------------------------------------------------------------------------------------- #pragma segment MAFinder void TPDocCommand::DoIt() // override { FailInfo fi; Try(fi) { gApplication->PrintDocuments(fFileList); fi.Success(); } else { this->ReportError(fi.error, fi.message); fi.ReSignal(); } } // TPDocCommand::DoIt //======================================================================================== // CLASS TAboutBoxCommand //======================================================================================== #undef Inherited #define Inherited TCommand #pragma segment MASelCommand DefineClass(TAboutBoxCommand, Inherited); //---------------------------------------------------------------------------------------- // TAboutBoxCommand: Empty constructor to satisfy the compiler. //---------------------------------------------------------------------------------------- #pragma segment ConstructorRes TAboutBoxCommand::TAboutBoxCommand() { } //---------------------------------------------------------------------------------------- // TAboutBoxCommand::IAboutBoxCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TAboutBoxCommand::IAboutBoxCommand(CommandNumber itsCommandNumber) { this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL); } // TAboutBoxCommand::IAboutBoxCommand //---------------------------------------------------------------------------------------- // TAboutBoxCommand::DoIt: //---------------------------------------------------------------------------------------- #pragma segment MAAboutApp void TAboutBoxCommand::DoIt() { gApplication->DoAboutBox(); } // TAboutBoxCommand::DoIt //======================================================================================== // CLASS TEventRetrieverCommand //======================================================================================== #undef Inherited #define Inherited TCommand #pragma segment MASelCommand DefineClass(TEventRetrieverCommand, Inherited); //---------------------------------------------------------------------------------------- // TEventRetrieverCommand: Empty constructor to satisfy the compiler. //---------------------------------------------------------------------------------------- #pragma segment ConstructorRes TEventRetrieverCommand::TEventRetrieverCommand() { } // TEventRetrieverCommand::TEventRetrieverCommand //---------------------------------------------------------------------------------------- // TEventRetrieverCommand::IEventRetrieverCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TEventRetrieverCommand::IEventRetrieverCommand(CommandNumber itsCommandNumber) { this->ICommand(itsCommandNumber, gApplication, kCantUndo, kDoesNotCauseChange, NULL); // Hang around fFreeOnCompletion = false; fRecurring = true; // Let more important stuff happen first fPriority = kPriorityLow; } // TEventRetrieverCommand::IEventRetrieverCommand //---------------------------------------------------------------------------------------- // TEventRetrieverCommand::NeedsToUnloadAllSegments: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TEventRetrieverCommand::NeedsToUnloadAllSegments() { return false; } // TEventRetrieverCommand::NeedsToUnloadAllSegments //---------------------------------------------------------------------------------------- // TEventRetrieverCommand::DoIt: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TEventRetrieverCommand::DoIt() { gApplication->PollToolboxEvent(gApplication->fAllowApplicationToSleep); } // TEventRetrieverCommand::DoIt #if qNeedsVU //======================================================================================== // CLASS TVUApplication //======================================================================================== #undef Inherited #define Inherited TCommandHandler #pragma segment MAInit DefineClass(TVUApplication, Inherited); //---------------------------------------------------------------------------------------- // TVUApplication constructor //---------------------------------------------------------------------------------------- #pragma segment MAInit TVUApplication::TVUApplication() { } // TVUApplication::TVUApplication //---------------------------------------------------------------------------------------- // TVUApplication::IVUApplication: //---------------------------------------------------------------------------------------- #pragma segment MAInit void TVUApplication::IVUApplication() { this->ICommandHandler(NULL); FailInfo fi; Try(fi) { gVUAssist = new TVUAssist(); gVUAssist->IVUAssist(gUGridViewInitialized); fi.Success(); } else { #if qDebug ProgramBreak("Can't initialize the virtual user assist object!"); #endif this->Free(); // we don't fail if we have no VU support gVUAssist = NULL; } } // TVUApplication::IVUApplication //---------------------------------------------------------------------------------------- // TVUApplication::Free: //---------------------------------------------------------------------------------------- #pragma segment MAClose void TVUApplication::Free() // override { gVUAssist = (TVUAssist*)FreeIfObject(gVUAssist); Inherited::Free(); } // TVUApplication::Free //---------------------------------------------------------------------------------------- // TVUApplication::AboutToLoseControl: //---------------------------------------------------------------------------------------- #pragma segment MAActivate void TVUApplication::AboutToLoseControl(Boolean) { if (gVUAssist) { gVUAssist->SuspendMole(); } } // TVUApplication::AboutToLoseControl //---------------------------------------------------------------------------------------- // TVUApplication::RegainControl: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TVUApplication::RegainControl(Boolean) { if (gVUAssist) { gVUAssist->ResumeMole(); } } // TVUApplication::RegainControl #endif //======================================================================================== // CLASS TApplication //======================================================================================== #undef Inherited #if qNeedsVU #define Inherited TVUApplication #else #define Inherited TCommandHandler #endif #pragma segment MAInit DefineClass(TApplication, Inherited); //---------------------------------------------------------------------------------------- // TApplication constructor //---------------------------------------------------------------------------------------- #pragma segment MAInit TApplication::TApplication() { // This is a special case. It needs to be available as soon as possible. gApplication = this; fMainFileType = 'TEXT'; fCreator = '\?\?\?\?'; fAllowApplicationToSleep = true; fAlwaysTrackCursor = false; fDone = false; fProcessNumber.highLongOfPSN = kNoProcess; fProcessNumber.lowLongOfPSN = kNoProcess; fClickCount = 0; fEventList = NULL; fPendingReplyList = NULL; fCursorRegion = NULL; fDocumentList = NULL; fEventLevel = 1; // Prevents UnloadAllSegs from getting called // if a modal dialogs is used befure starting // the main event loop fFreeWindowList = NULL; fHeadCohandler = NULL; fHelpRegion = NULL; fIdlePhase = idleEnd; fInBackground = false; // When we start an app, it's in foreground fLastClickPart = inDesk; fLastMousePoint = gZeroPt; fLastUpTime = TickCount(); fLaunchWithNewDocument = true; fLowSpaceInterval = kLowSpaceInterval; fMainEventMask = everyEvent; fDisplayedMenus = kMBarDisplayed; fOtherMenus = kMBarNotDisplayed; fMBarHierarchical = kMBarHierarchical; fNextSpaceMessage = TickCount(); fSleepRegion = NULL; fSysWindowActive = false; fTarget = this; fUndoCommand = cNoCommand; fUndoState = kShowUndo; #if qDebug fDebugFlagsWindow = NULL; #endif } // TApplication::TApplication //---------------------------------------------------------------------------------------- // TApplication::IApplication: //---------------------------------------------------------------------------------------- #pragma segment MAInit void TApplication::IApplication(OSType itsMainFileType, OSType itsCreator) { #if qNeedsVU this->IVUApplication(); #else this->ICommandHandler(NULL); #endif FailInfo fi; Try(fi) { fMainFileType = itsMainFileType; fCreator = itsCreator; fSleepRegion = MakeNewRgn(); fCursorRegion = MakeNewRgn(); fHelpRegion = MakeNewRgn(); if (qNeedsProcessMgr || gConfiguration.hasProcessMgr) FailOSErr(GetCurrentProcess(&fProcessNumber)); fFreeWindowList = NewList(); #if qDebug fFreeWindowList->SetEltType("TWindow"); #endif fDocumentList = NewList(); #if qDebug fDocumentList->SetEltType("TDocument"); #endif // Posted commands won't go anywhere until we create the queue TEventList * anEventList = new TEventList; anEventList->IEventList(); fEventList = anEventList; #if qDebug fEventList->SetEltType("TEvent"); #endif anEventList = new TEventList; anEventList->IEventList(); fPendingReplyList = anEventList; #if qDebug fPendingReplyList->SetEltType("TClientCommand"); #endif // Allocate the global dependencyspace gMacAppDependencySpace this->DoMakeDependencySpace(); // Make the command that operates the main Event Loop TEventRetrieverCommand * aEventCommand = new TEventRetrieverCommand; aEventCommand->IEventRetrieverCommand(cNoCommand); this->PostCommand(aEventCommand); // Install the default tab behavior TMultiWindowTabber * aTabber = new TMultiWindowTabber; aTabber->IMultiWindowTabber(true); this->AddBehavior(aTabber); // Create the MenuBar manager object gMenuBarManager = this->MakeMenuBarManager(); this->DoMakeViewServer(); // creates the view server fi.Success(); } else { #if qDebug ProgramBreak("Can't initialize the application object!"); #endif this->Free(); gApplication = NULL; fi.ReSignal(); } } // TApplication::IApplication //---------------------------------------------------------------------------------------- // TApplication::MakeMenuBarManager: //---------------------------------------------------------------------------------------- #pragma segment MAInit // This function is called by IApplication to create the menu bar manager object. TMenuBarManager* TApplication::MakeMenuBarManager() { TMenuBarManager* theMenuBarManager; theMenuBarManager = new TMenuBarManager; theMenuBarManager->IMenuBarManager( fOtherMenus ); return theMenuBarManager; } // TApplication::MakeMenuBarManager //---------------------------------------------------------------------------------------- // TApplication::AboutToLoseControl: //---------------------------------------------------------------------------------------- #pragma segment MAActivate void TApplication::AboutToLoseControl(Boolean convertClipboard) { #if qNeedsVU Inherited::AboutToLoseControl(convertClipboard); #endif gClipboardMgr->AboutToLoseControl(convertClipboard); // Let all windows know that we're losing control - e.g. so floaters can hide // themselves CWMgrIterator iter; for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow()) { TWindow * aWindow = this->WMgrToWindow(aWinPtr); if (aWindow) aWindow->AboutToLoseControl(); } this->ActivateBusyCursor(false); // Don't want busy cursor while in DA } // TApplication::AboutToLoseControl //---------------------------------------------------------------------------------------- // TApplication::ActivateBusyCursor: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::ActivateBusyCursor(Boolean entering) { if (gBusyCursor) gBusyCursor->Activate(entering); } // TApplication::ActivateBusyCursor //---------------------------------------------------------------------------------------- // TApplication::AddDocument: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TApplication::AddDocument(TDocument* aNewDocument) { if (fDocumentList) fDocumentList->Insert(aNewDocument); } // TApplication::AddDocument //---------------------------------------------------------------------------------------- // TApplication::AddWindow: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TApplication::AddWindow(TWindow* aWindow) { // Protect against double installation if (fFreeWindowList && (fFreeWindowList->GetIdentityItemNo(aWindow) == 0)) fFreeWindowList->Insert(aWindow); } // TApplication::AddWindow //---------------------------------------------------------------------------------------- // TApplication::AlertFilter: AlertFilter is a default filterProc used by MacAppAlert if // the filterProc passed in is NULL. It maps key strokes to the first character of button // item titles. It also hands off activate and update processing to gApplication if we're // not being called from an error condition or while nested. //---------------------------------------------------------------------------------------- #pragma segment MAGlobalsRes // Don't require a segment load for this Boolean TApplication::AlertFilter(DialogPtr theDialog, EventRecord& theEvent, short& itemHit) { static CStr31 bufferString; // Must be a global, since it's used each // time the alert filter is entered. (It // could be a field of TApplication...) If // any script has a character with more // than 31 bytes then the creatures that // speak that language have too many // fingers! CRect box; short byteType; EventRecord anEvent; TToolboxEvent * event; Boolean oldObjectPerm; Boolean oldInFilterState = gInFilter; Boolean returnValue = false; VOLATILE(oldInFilterState); VOLATILE(returnValue); gInFilter = true; // First call the minimal alert filter; if it does not handle the // event, do some more complex handling returnValue = MinimalAlertFilter(theDialog, theEvent, itemHit); if( returnValue == false ) { FailInfo fi; Try(fi) { // Wouldn't want MacApp to get lied to about where the focus _Actually_ is if (!gInhibitNestedHandling &&!oldInFilterState) this->InvalidateFocus(); switch (theEvent.what) { // this is the first event the alert gets, use it to initialize the global buffer case activateEvt: if (((DialogPtr)theEvent.message) == theDialog) bufferString = gEmptyString; // initialize bufferString else if (!gInhibitNestedHandling &&!oldInFilterState) { GrafPtr savePort; GetPort(&savePort); oldObjectPerm = AllocateObjectsFromPerm(false); event = new TToolboxEvent; AllocateObjectsFromPerm(oldObjectPerm); event->IToolboxEvent(this, theEvent); event->Process(); SetPort(savePort); } break; // this is the first event the alert gets, so let's determine our VARs case updateEvt: if (((DialogPtr)theEvent.message) != theDialog) if (!gInhibitNestedHandling &&!oldInFilterState) { GrafPtr savePort; GetPort(&savePort); oldObjectPerm = AllocateObjectsFromPerm(false); event = new TToolboxEvent; AllocateObjectsFromPerm(oldObjectPerm); event->IToolboxEvent(this, theEvent); event->Process(); SetPort(savePort); } break; // let's determine if the key pressed corresponds to our button titles case keyDown: oldObjectPerm = AllocateObjectsFromPerm(false); event = new TToolboxEvent; AllocateObjectsFromPerm(oldObjectPerm); event->IToolboxEvent(this, theEvent); this->GetTarget()->KeyEventToComponents(event);// Find out what keys were _REALLY_ pressed bufferString += event->fCharacter; event = (TToolboxEvent*)FreeIfObject(event); byteType = CharByte((Ptr)(&bufferString[1]), bufferString.Length() - 1); switch (byteType) { case smSingleByte: if (CompareAlertKeysToItem(theDialog, bufferString, itemHit)) { DoAlertKeyDown(theDialog, itemHit); returnValue = true; } bufferString = gEmptyString; // Clear the buffer for the next time around. break; case smFirstByte: case smMiddleByte: break; case smLastByte: if (CompareAlertKeysToItem(theDialog, bufferString, itemHit)) { DoAlertKeyDown(theDialog, itemHit); returnValue = true; } bufferString = gEmptyString; // Clear the buffer for the next time around. break; } } // Idle but only if _REALLY_ necessary if (!gInhibitNestedHandling &&!oldInFilterState &&!EventAvail(everyEvent, &anEvent)) this->Idle(fIdlePhase); fi.Success(); } } gInFilter = oldInFilterState; return returnValue; } // TApplication::AlertFilter //---------------------------------------------------------------------------------------- // TApplication::AppleEventIdleProc: //---------------------------------------------------------------------------------------- #pragma segment MAGlobalsRes // Don't require a segment load for this Boolean TApplication::AppleEventIdleProc(EventRecord& theEventRecord, long&/* sleepTime */ , RgnHandle&/* mouseRgn */ ) { if ((theEventRecord.what == activateEvt) || (theEventRecord.what == updateEvt)) { Boolean oldObjectPerm = AllocateObjectsFromPerm(false); TToolboxEvent* event = new TToolboxEvent; AllocateObjectsFromPerm(oldObjectPerm); event->IToolboxEvent(this, theEventRecord); event->Process(); } return false; } // TApplication::AppleEventIdleProc //---------------------------------------------------------------------------------------- // TApplication::StandardFileFilter: //---------------------------------------------------------------------------------------- #pragma segment MAGlobalsRes // Don't require a segment load for this Boolean TApplication::StandardFileFilter(DialogPtr/* theDialog */, EventRecord& theEvent, short&/* itemHit */ , void*/* yourDataPtr*/ ) { this->InvalidateFocus(); switch (theEvent.what) { case activateEvt: case updateEvt: // check if intended for a MacApp window if (!this->WMgrToWindow((WindowPtr)theEvent.message)) break; // drop thru to processing the event case osEvt: case kHighLevelEvent: { GrafPtr savePort; GetPort(&savePort); // If the port get changed behind us // the dialog can't find its controls Boolean oldObjectPerm = AllocateObjectsFromPerm(false); TToolboxEvent* event = new TToolboxEvent; AllocateObjectsFromPerm(oldObjectPerm); event->IToolboxEvent(NULL, theEvent); ++fEventLevel; event->Process(); --fEventLevel; SetPort(savePort); } break; } return false; // did not take the event } // TApplication::StandardFileFilter //---------------------------------------------------------------------------------------- // TApplication::FindDocument: //---------------------------------------------------------------------------------------- #pragma segment MAFile TDocument* TApplication::FindDocument(TFile* aFile) { CDocumentIterator iter(this); for (TDocument * aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument()) if (aDocument->FindDocument(aFile)) return aDocument; return NULL; // No document already open } // TApplication::FindDocument //---------------------------------------------------------------------------------------- // TApplication::Beep: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::Beep(short duration) { SysBeep(duration); } // TApplication::Beep //---------------------------------------------------------------------------------------- // TApplication::CanOpenDocument: //---------------------------------------------------------------------------------------- #pragma segment MAFinder // This is called only when opening/printing from the finder and from standard file; // it simulates the filtering done by Std File. Boolean TApplication::CanOpenDocument(CommandNumber itsCommandNumber, TFile* aFile) { short dlgID; CPoint where; ProcPtr fileFilter; ProcPtr dlgHook; ProcPtr modalFilter; ProcPtr activateProc; Ptr activeList; void *yourDataPtr = NULL; TypeListHandle typeList; CInfoPBRec paramBlock; Boolean returnValue = false; CStr63 fileName; this->GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where, dlgHook, modalFilter, activeList, activateProc, yourDataPtr); aFile->GetName(fileName); short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType)); if (numTypes == 0) { if (!fileFilter) returnValue = true; // no file filter then want all types else if (aFile->GetCatInfo(paramBlock) == noErr) { paramBlock.hFileInfo.ioNamePtr = (StringPtr)fileName; // Call through the supplied filterProc if (qNeedsAliasMgr || gConfiguration.hasAliasMgr) returnValue =!((FileFilterYDProcPtr)fileFilter)((ParamBlockRec*)¶mBlock, NULL); else returnValue =!((FileFilterProcPtr)fileFilter)((ParamBlockRec*)¶mBlock); } else returnValue = false; } else for (short i = 0; i < numTypes; ++i) if (((long)(aFile->fFileType)) == ((long)(*typeList)[i])) { if (!fileFilter) returnValue = true; else if (aFile->GetCatInfo(paramBlock) == noErr) { paramBlock.hFileInfo.ioNamePtr = (StringPtr)fileName; // Call through the supplied filterProc if (qNeedsAliasMgr || gConfiguration.hasAliasMgr) returnValue =!((FileFilterYDProcPtr)fileFilter)((ParamBlockRec*)¶mBlock, NULL); else returnValue =!((FileFilterProcPtr)fileFilter)((ParamBlockRec*)¶mBlock); } else returnValue = false; break; } typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList); return returnValue; } // TApplication::CanOpenDocument //---------------------------------------------------------------------------------------- // TApplication::ChooseApplication: //---------------------------------------------------------------------------------------- #pragma segment MAOpen Boolean TApplication::ChooseApplication(AEAddressDesc& theAddress) { // typedef TargetID* TargetIDPtr, // ** TargetIDHdl; TargetIDHdl theTargetID; LocationNameRec theLoc; PortInfoRec thePortInfo; OSErr theErr; CStr32 theLocNBPType; Boolean returnValue = false; if (qNeedsAppleEventMgr || gConfiguration.hasAppleEventMgr) { theErr = PPCBrowser(gEmptyString, gEmptyString, false, &theLoc, &thePortInfo, NULL, gEmptyString); if (theErr == noErr) { theTargetID = (TargetIDHdl) NewPermHandle(sizeof(TargetID)); (*theTargetID)->location = theLoc; (*theTargetID)->name = thePortInfo.name; theAddress.descriptorType = typeTargetID; theAddress.dataHandle = (Handle)theTargetID; returnValue = true; } else if (theErr != userCanceledErr) FailOSErr(theErr); } return returnValue; } // TApplication::ChooseApplication //---------------------------------------------------------------------------------------- // TApplication::ChooseDocument: //---------------------------------------------------------------------------------------- #pragma segment MAOpen Boolean TApplication::ChooseDocument(CommandNumber itsCommandNumber, TList** aFileList) { typedef SFTypeList* SFTypeListPtr; typedef SFTypeListPtr* SFTypeListHandle; short dlgID; CPoint where; ProcPtr fileFilter; ProcPtr dlgHook; ProcPtr modalFilter; ProcPtr activateProc; Ptr activeList; void* yourDataPtr = NULL; TypeListHandle typeList; SFTypeListPtr pTypeList; short numTypes; Boolean fileChosen; TFile * aFile = NULL; VOLATILE(aFileList); VOLATILE(aFile); this->GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where, dlgHook, modalFilter, activeList, activateProc, yourDataPtr); numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType)); if (numTypes == 0) { numTypes = -1; // Tell Std File to display all types. pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory } else { LockHandleHigh((Handle)typeList); // in case Std File does allocations pTypeList = *((SFTypeListHandle)typeList); } #if qDebug // Causes TApplication::GetEvent to call CheckRsrcUsage. gRsrcCheck = 0; #endif FailInfo fi; Try(fi) { aFile = this->DoMakeFile(itsCommandNumber); fileChosen = false; FailOSErr(MAInteractWithUser(kNoTimeOut, gNotificationPtr, gMacAppAppleEventIdleProc)); if (yourDataPtr == NULL) { yourDataPtr = &itsCommandNumber; } #if !qPowerPC if (gConfiguration.hasCustomFile) { #endif StandardFileReply customReply; gClipboardMgr->AboutToLoseControl(true); // so scrap gets converted FileFilterYDUPP cgfFileFilter = NewFileFilterYDProc(fileFilter); DlgHookYDUPP cgfDlgHook = NewDlgHookYDProc(dlgHook); ModalFilterYDUPP cgfModalFilter = NewModalFilterYDProc(modalFilter); ActivateYDUPP cgfActivateProc = NewActivateYDProc(activateProc); CustomGetFile(cgfFileFilter, numTypes, (*pTypeList), &customReply, dlgID, where, cgfDlgHook, cgfModalFilter, (short*)activeList, cgfActivateProc, yourDataPtr); cgfFileFilter = (FileFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfFileFilter); cgfDlgHook = (DlgHookYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfDlgHook); cgfModalFilter = (ModalFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfModalFilter); cgfActivateProc = (ActivateYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfActivateProc); gClipboardMgr->RegainControl(true); // so scrap gets converted fileChosen = customReply.sfGood; if (fileChosen) aFile->SpecifyWithStandardFileReply(customReply); #if !qPowerPC // the following block of code is the "else" block for the above Gestalt check - // as with that check, it is only relevant if we are not built for PowerPC } else { SFReply reply; // We will pass the address of the CallBack instead of the modalFilter to // SFPGetFile It will add yourDataPtr parameter before passing on to the // ModalFilterProc supplied by SFPutParms this lets us assume a single calling // convention for that function. // Don't create a CallBack when the SF callback is NULL. // Also, pass itsCommandNumber as a default yourDataPtr. CallBack myFileFilterCallBack; SetCallBack(fileFilter, (long)yourDataPtr, &myFileFilterCallBack); FileFilterProcPtr aFileFilterProcPtr = fileFilter ? (FileFilterProcPtr)&myFileFilterCallBack : NULL; CallBack myModalHookCallBack; SetCallBack(dlgHook, (long)yourDataPtr, &myModalHookCallBack); DlgHookProcPtr aDlgHookProcPtr = dlgHook ? (DlgHookProcPtr)&myModalHookCallBack : NULL; CallBack myModalFilterCallBack; SetCallBack(modalFilter, (long)yourDataPtr, &myModalFilterCallBack); ModalFilterProcPtr aModalFilterProcPtr = modalFilter ? (ModalFilterProcPtr)&myModalFilterCallBack : NULL; gClipboardMgr->AboutToLoseControl(true); // so scrap gets converted SFPGetFile(where, gEmptyString, aFileFilterProcPtr, numTypes, (*pTypeList), aDlgHookProcPtr, &reply, dlgID, aModalFilterProcPtr); gClipboardMgr->RegainControl(true); // so scrap gets converted fileChosen = reply.good; if (fileChosen) FailOSErr(aFile->SpecifyWithSFReply(reply)); } #endif fi.Success(); } else // Recover { typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList); aFile = (TFile *)FreeIfObject(aFile); fi.ReSignal(); } typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList); if (fileChosen) { FailInfo fi; Try(fi) { // Return the file(s) chosen *aFileList = NewList(); (*aFileList)->InsertLast(aFile); fi.Success(); } else { if (*aFileList) *aFileList = (TList*)FreeIfObject(*aFileList); aFile = (TFile*)FreeIfObject(aFile); fi.ReSignal(); } } else // user cancelled or something aFile = (TFile *)(FreeIfObject(aFile)); // free the unwanted file object return fileChosen; } // TApplication::ChooseDocument //---------------------------------------------------------------------------------------- // TApplication::Close: //---------------------------------------------------------------------------------------- #pragma segment MATerminate void TApplication::Close() { // Close all of the visible non-floater windows WindowPtr aWMgrWindow; while ((aWMgrWindow = MAFrontWindow()) != NULL) this->CloseToolboxWindow(aWMgrWindow); // Close all of the windows while ((aWMgrWindow = FrontWindow()) != NULL) this->CloseToolboxWindow(aWMgrWindow); // Close any windowless documents. Add a block for failure handling { CDocumentIterator iter(this); TDocument * clipDocument = NULL; if (gClipboardMgr->fClipView) clipDocument = gClipboardMgr->fClipView->fDocument; for (TDocument * aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument()) if (!clipDocument || aDocument != clipDocument) aDocument->CloseAndFree(); } // Close down the cohandler chain. Add a block for failure handling { CHandlerIterator iter(fHeadCohandler); for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler()) FreeIfObject(aHandler); } gClipboardMgr->Close(); gViewServer = (TViewServer *)FreeIfObject(gViewServer); // won't be creating any more views... } // TApplication::Close //---------------------------------------------------------------------------------------- // TApplication::CloseToolboxWindow: //---------------------------------------------------------------------------------------- #pragma segment MAClose void TApplication::CloseToolboxWindow(WindowPtr aWMgrWindow) { TWindow * aWindow; if (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!IsDeskAccessory(aWMgrWindow)) { aWindow = this->WMgrToWindow(aWMgrWindow); if (aWindow) aWindow->CloseByUser(); else HideWindow(aWMgrWindow); } else CloseDeskAcc(((WindowPeek)aWMgrWindow)->windowKind); } // TApplication::CloseToolboxWindow //---------------------------------------------------------------------------------------- // TApplication::CountClicks: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes short TApplication::CountClicks(TToolboxEvent* event, short whereMouseDown) { short newClickCount; newClickCount = 1; if ((whereMouseDown == fLastClickPart) && // clicked in the same place… (fClickCount > 0) && // not the first click… (event->fEventRecord.when - fLastUpTime < GetDblTime()) &&// close enough in time… this->GetTarget()->DoMultiClick(fLastMousePoint, event->fEventRecord.where))// close enough in space newClickCount = fClickCount + 1; fLastMousePoint = event->fEventRecord.where; fLastClickPart = whereMouseDown; fClickCount = newClickCount; return newClickCount; } // TApplication::CountClicks //---------------------------------------------------------------------------------------- // TApplication::DeleteDocument: //---------------------------------------------------------------------------------------- #pragma segment MAClose void TApplication::DeleteDocument(TDocument* docToDelete) { if (fDocumentList) fDocumentList->Delete(docToDelete); } // TApplication::DeleteDocument //---------------------------------------------------------------------------------------- // TApplication::DeleteWindow: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DeleteWindow(TWindow* windowToDelete) { if (fFreeWindowList) fFreeWindowList->Delete(windowToDelete); } // TApplication::DeleteWindow //---------------------------------------------------------------------------------------- // TApplication::DispatchEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DispatchEvent(TToolboxEvent* event) { // For Toolbox events, fIdentifier == fEventRecord.what if (event) { switch (event->fIdentifier) { case mouseUp: this->HandleMouseUp(event); break; case mouseDown: this->HandleMouseDown(event); break; case activateEvt: this->HandleActivateEvent(event); break; case updateEvt: this->HandleUpdateEvent(event); break; case keyDown: case autoKey: this->HandleKeyDownEvent(event); break; case keyUp: // A MultiFinder™ bug (at least up to 6.0) keep us from reliably getting // keyUp events after minor context switches (background updates, etc.). // It replaces the global event mask (which we would have had to change to // get keyups in the first place) with the wrong mask. Fixed in system 7.0 this->HandleKeyUpEvent(event); break; case diskEvt: this->HandleDiskEvent(event); break; case osEvt: this->HandleSystemEvent(event); break; case nullEvent: case networkEvt: case driverEvt: case app1Evt: case app2Evt: case app3Evt: this->HandleAlienEvent(event); break; case kHighLevelEvent: this->HandleHighLevelEvent(event); break; default: this->HandleAlienEvent(event); break; } } } // TApplication::DispatchEvent //---------------------------------------------------------------------------------------- // TApplication::DispatchAppleEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes OSErr TApplication::DispatchAppleEvent(const AppleEvent& message, const AppleEvent& reply, long info) { OSErr theErr = noErr; // Wrap this in a failure handler so that if failure occured or the event was not // handled we will inform the AppleEvent manager. FailInfo fi; Try(fi) { if (info != cAppleEventReply) this->GetTarget()->HandleAppleCommand(info, message, reply); else // Since the reply is actually in the message, the reply (reply to the reply) // AppleEvent is NULL and can be discarded this->MatchReplyToPending(message); fi.Success(); } else { // Since the event was probably suspended, we reset it with AESetTheCurrentEvent // and let the AppleEvent manager will take care of disposing of the event. // Don't resignal here since we HAVE to return through the AppleEvent manager // or the package will remain locked in the system heap (until the next time you // reboot). AESetTheCurrentEvent(&message); theErr = fi.error; } return theErr; } // TApplication::DispatchAppleEvent //---------------------------------------------------------------------------------------- // TApplication::MatchReplyToPending: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::MatchReplyToPending(const AppleEvent& reply) { TAppleEvent * theReply = NULL; TClientCommand * theMatchedCommand = NULL; theReply = new TAppleEvent; theReply->InitializeFromMessage(reply, false); // Higher priority events are at the end of the list. CObjectIterator iter(fPendingReplyList, kIterateBackward); for (TClientCommand * aCommand = (TClientCommand *)iter.FirstObject(); iter.More(); aCommand = (TClientCommand *)iter.NextObject()) { if (aCommand->GetReturnID() == theReply->GetReturnID()) { theMatchedCommand = aCommand; break; } } if (theMatchedCommand) { fPendingReplyList->Delete(theMatchedCommand); theMatchedCommand->ProcessReply(theReply); this->PostCommand(theMatchedCommand); } else // No match found theReply = (TAppleEvent *)FreeIfObject(theReply); } // TApplication::MatchReplyToPending //---------------------------------------------------------------------------------------- // TApplication::DoAppleCommand: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoAppleCommand(CommandNumber aCommandNumber, const AppleEvent& message, const AppleEvent& reply) { switch (aCommandNumber) { case cFinderNew: // Special case the old MacPaint style open if user knows about the option // key. Only if the application is frontmost though. if (this->IsFrontProcess() && IsOptionKeyDown()) this->HandleMenuCommand(cOpen); else if (fLaunchWithNewDocument) this->GetTarget()->HandleMenuCommand(cFinderNew); break; case cFinderOpen: { TODocCommand * anODocCommand = new TODocCommand; anODocCommand->InitializeFromAppleEvent(aCommandNumber, this, kCantUndo, kDoesNotCauseChange, NULL, message, reply); this->PostCommand(anODocCommand); break; } case cFinderPrint: { TPDocCommand * aPDocCommand = new TPDocCommand; aPDocCommand->InitializeFromAppleEvent(aCommandNumber, this, kCantUndo, kDoesNotCauseChange, NULL, message, reply); this->PostCommand(aPDocCommand); break; } case cFinderQuit: this->GetTarget()->HandleMenuCommand(cQuit); break; default: Inherited::DoAppleCommand(aCommandNumber, message, reply); break; } } // TApplication::DoAppleCommand //---------------------------------------------------------------------------------------- // TApplication::DoCommandKeyEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoCommandKeyEvent(TToolboxEvent* event)// override { if (!event->IsAutoKeyEvent()) { this->SetupTheMenus(); // If you want to have case sensitive command keys use the following line because // KeyEventToComponents returns the correct character for shifted keys when the // command key is down. That lets us test for things like command-period // correctly. So in order to be backward compatible (sigh) we now have to ignore // the _correct_ char that is passed in (and is in event->fCharacter) and use the // old ToolBox supplied unPasteurized character that is left in the actual // EventRecord // this->MenuEvent(MenuKey(event->fCharacter)); this->MenuEvent(MenuKey((unsigned char)(((event->fEventRecord.message) & charCodeMask)))); } else Inherited::DoCommandKeyEvent(event); } // TApplication::DoCommandKeyEvent //---------------------------------------------------------------------------------------- // TApplication::DoKeyEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoKeyEvent(TToolboxEvent* event)// override { switch (event->fKeyCode) { case kF1VirtualCode: this->SetupTheMenus(); if (CommandEnabled(cUndo)) this->GetTarget()->HandleMenuCommand(cUndo); break; case kF2VirtualCode: this->SetupTheMenus(); if (CommandEnabled(cCut)) this->GetTarget()->HandleMenuCommand(cCut); break; case kF3VirtualCode: this->SetupTheMenus(); if (CommandEnabled(cCopy)) this->GetTarget()->HandleMenuCommand(cCopy); break; case kF4VirtualCode: this->SetupTheMenus(); if (CommandEnabled(cPaste)) this->GetTarget()->HandleMenuCommand(cPaste); break; case kClearVirtualCode: this->SetupTheMenus(); if (CommandEnabled(cClear)) this->GetTarget()->HandleMenuCommand(cClear); break; default: Inherited::DoKeyEvent(event); break; } } // TApplication::DoKeyEvent //---------------------------------------------------------------------------------------- // TApplication::DoMakeDocument: // // E X A M P L E // { // TDocument* aYOURDocument = NULL; // // aYOURDocument = new TDocument; // aYOURDocument->IYOURDocument(); // return aYOURDocument; // } //---------------------------------------------------------------------------------------- #pragma segment MANever TDocument* TApplication::DoMakeDocument(CommandNumber, TFile*) { this->SubClassResponsibility(); return NULL; // So that CFront doesn't complain } // TApplication::DoMakeDocument //---------------------------------------------------------------------------------------- // TApplication::DoMakeFile: //---------------------------------------------------------------------------------------- #pragma segment MAOpen TFile* TApplication::DoMakeFile(CommandNumber) { return NewFile(fMainFileType, fCreator, kUsesDataFork, kUsesRsrcFork, !kDataOpen, !kRsrcOpen); } // TApplication::DoMakeFile //---------------------------------------------------------------------------------------- // TApplication::DoMenuCommand: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TApplication::DoMenuCommand(CommandNumber aCommandNumber) { // =================================================================================== // Some commands will be posted to perform actions that must _ALWAYS_ be available. // The allocation cannot be allowed to fail. So we do a temp allocation which by // definition cannot be allowed to fail. This strategy is used wherever we want to use // command objects but don't want to leave the user twisting in the breeze. NOTE: // Don't forget to allow for this memory in your mem! resource if you copy this style // in your own code. // =================================================================================== Boolean oldObjectPerm; TQuitCommand * aQuitCommand; TNewDocumentCommand * aNewDocCommand; TAboutBoxCommand * aAboutAppCommand; switch (aCommandNumber) { case cQuit: oldObjectPerm = AllocateObjectsFromPerm(false); aQuitCommand = new TQuitCommand; AllocateObjectsFromPerm(oldObjectPerm); aQuitCommand->IQuitCommand(aCommandNumber); this->PostCommand(aQuitCommand); break; case cNew: // cNew..cNewLast: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case cNewLast: case cFinderNew: aNewDocCommand = new TNewDocumentCommand; aNewDocCommand->INewDocumentCommand(aCommandNumber); this->PostCommand(aNewDocCommand); break; case cOpen: // cOpen..cOpenLast: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case cOpenLast: { TList * aFileList = NULL; VOLATILE(aFileList); if (this->ChooseDocument(aCommandNumber, &aFileList)) { TODocCommand* anODocCommand = NULL; FailInfo fi; Try(fi) { anODocCommand = new TODocCommand; anODocCommand->IODocCommand(aCommandNumber, aFileList); fi.Success(); } else // Recover { // We can try to free the file list here because at the point where // IODocCommand could fail, it will not have made the assignment of // aFileList. aFileList = (TList *)(FreeIfObject(aFileList)); fi.ReSignal(); } this->PostCommand(anODocCommand); } break; } case cClose: if (qDebug && this->WMgrToWindow(FrontWindow())) ProgramBreak("The frontmost window is a window object but didn't handle the cClose CommandNumber, your TWindow subclass probably forgot to call Inherited::DoMenuCommand!"); this->CloseToolboxWindow(FrontWindow());// TWindow would have handled the command // before we get here so the window is break; // probably a DA or something case cAboutApp: aAboutAppCommand = new TAboutBoxCommand; aAboutAppCommand->IAboutBoxCommand(aCommandNumber); this->PostCommand(aAboutAppCommand); break; #if qDebug case cDebugFlags: { if (!fDebugFlagsWindow) FailNIL(fDebugFlagsWindow = gViewServer->NewTemplateWindow(kDebugFlagsView, NULL)); fDebugFlagsWindow->Open(); fDebugFlagsWindow->Select(); break; } case cRefreshFrontWindow: { TWindow * aWindow = this->GetActiveWindow(kNoFloaters); if (aWindow) aWindow->ForceRedraw(); break; } case cDoFirstClick: { TWindow * aWindow = this->GetActiveWindow(kNoFloaters); if (aWindow) aWindow->fDoFirstClick =!aWindow->fDoFirstClick; break; } // System Justification - see comment in Debug.r // case cSetSysJust: // swap the current setting // if (GetSysDirection() == smSysJustLeft) // SetSysDirection(smSysJustRight); // else // SetSysDirection(smSysJustLeft); // break; #endif #if qPerform case cPerfMonInit: { TWindow* aWindow; IDType dismisser; FailNIL(aWindow = gViewServer->NewTemplateWindow(kPerfMonInitView, NULL)); dismisser = aWindow->PoseModally(); if (dismisser == 'init') InitiatePerfMonitor(aWindow); aWindow->CloseAndFree(); break; } case cPerfMonDump: { StandardFileReply replyRec; StandardPutFile((StringPtr)"\pSave as:", (StringPtr)"\puntitled", &replyRec); if (replyRec.sfGood) DumpPerfMonitor(replyRec.sfFile); break; } case cPerfMonToggle: { EnablePerfMonitor(!PerfMonitorEnabled()); break; } case cPerfMonEnd: { TerminatePerfMonitor(); //MW I added this break; was there a reason it was missing? break; } #endif default: Inherited::DoMenuCommand(aCommandNumber); break; } } // TApplication::DoMenuCommand //---------------------------------------------------------------------------------------- // TApplication::DoSetupMenus: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoSetupMenus() { Inherited::DoSetupMenus(); gMenuBarManager->SetPreferredMenuBarID(fDisplayedMenus); gMenuBarManager->SetPreferredHierMenuBarID(fMBarHierarchical); Boolean lowSpace = MemSpaceIsLow(); Enable(cAboutApp, true); Enable(cQuit, fEventLevel <= 1); // Can't enable Quit if in nested event handling Enable(cNew, !lowSpace); Enable(cOpen, !lowSpace); WindowPtr aWindowPtr = FrontWindow(); if ((aWindowPtr) && (this->WMgrToWindow(aWindowPtr) == NULL)) // window objects will take care of themselves, but we take care of the indigent. Enable(cClose, ((WindowPeek)aWindowPtr)->goAwayFlag != false); } // TApplication::DoSetupMenus //---------------------------------------------------------------------------------------- // TApplication::DoAboutBox: Method to display the "About" box for your application. // Override to do interesting things. Since it is normally called from a command; the app // usually has the maximum free space available. //---------------------------------------------------------------------------------------- #pragma segment MAAboutApp void TApplication::DoAboutBox() { CStr255 apName; FailSpaceIsLow(); this->GetApplicationName(apName); ParamText((ConstStr255Param)&apName, (ConstStr255Param)&gEmptyString, (ConstStr255Param)&gEmptyString, (ConstStr255Param)&gEmptyString); // Put Application name in the about box hadCreditsStringList = (GetResource('STR#', kDefaultCredits) != NULL); if (hadCreditsStringList) { lastCreditsStringIndex = 1; lastCreditsShownTicks = TickCount(); waitTicks = 5 * 60; originalText = (CStringHandle)NewString(gEmptyString); FailNIL(originalText); MacAppAlert(phAboutApp, (ProcPtr) & DoShowAboutAppFilter); originalText = (CStringHandle)DisposeIfHandle((Handle)originalText); } else StdAlert(phAboutApp); } // TApplication::DoAboutBox //---------------------------------------------------------------------------------------- // TApplication::DoMakeDependencySpace: //---------------------------------------------------------------------------------------- #pragma segment MAInit void TApplication::DoMakeDependencySpace() { TSimpleDependencySpace* aDependencySpace = NULL; aDependencySpace = new TSimpleDependencySpace; aDependencySpace->ISimpleDependencySpace(); gMacAppDependencies = aDependencySpace; } //---------------------------------------------------------------------------------------- // TApplication::GetDefaultCursorRegion: Make the region the desktop less the active // window, and any first click windows. The current mouse location is added in // TApplication::TrackCursor. //---------------------------------------------------------------------------------------- void TApplication::GetDefaultCursorRegion(CPoint /* globalMouse */, RgnHandle cursorRegion) { // Start off with the "desktop region" GetDeskTopRegion(cursorRegion); // Remove the visRgn of all windows for which TestWindow returns true CWMgrIterator iter; for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow()) { TWindow * aWindow = this->WMgrToWindow(aWinPtr); if (aWindow && (aWindow->IsShown() && aWindow->HandlesCursor()) && aWindow->Focus()) { // Convert the visRgn to global coordinates. We focused on the window because // the visRgn is in the coordinates of the current port aWindow->LocalToSuperRegion(aWinPtr->visRgn); // Remove the visRgn from the cursor region DiffRgn(cursorRegion, aWinPtr->visRgn, cursorRegion); // Convert the visRgn back to local (port) coordinates aWindow->SuperToLocalRegion(aWinPtr->visRgn); } } } // TApplication::GetDefaultCursorRegion //---------------------------------------------------------------------------------------- // TApplication::InstallHelpMenuItems: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::InstallHelpMenuItems() { // abstract method; override to install your help menu item(s). Use // gMenuBarManager->AddHelpMenuItem( "^0 Help", kYourHelpCommandNumber ); } // TApplication::InstallHelpMenuItems //---------------------------------------------------------------------------------------- // TApplication::GetDefaultHelpRegion: Make the region the desktop less the active window, // and any first click windows. The current mouse location is added in // TApplication::TrackHelp. //---------------------------------------------------------------------------------------- void TApplication::GetDefaultHelpRegion(CPoint /* globalMouse */, RgnHandle helpRegion) { // Start off with the "desktop region" GetDeskTopRegion(helpRegion); // Remove the visRgn of all windows for which TestWindow returns true CWMgrIterator iter; for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow()) { TWindow * aWindow = this->WMgrToWindow(aWinPtr); if (aWindow && (aWindow->IsShown() && aWindow->HandlesHelp()) && aWindow->Focus()) { // Convert the visRgn to global coordinates. We focused on the window because // the visRgn is in the coordinates of the current port aWindow->LocalToSuperRegion(aWinPtr->visRgn); // Remove the visRgn from the cursor region DiffRgn(helpRegion, aWinPtr->visRgn, helpRegion); // Convert the visRgn back to local (port) coordinates aWindow->SuperToLocalRegion(aWinPtr->visRgn); } } } // TApplication::GetDefaultHelpRegion //---------------------------------------------------------------------------------------- // TApplication::GetHelpParameters: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::GetHelpParameters(ResNumber helpResource, short helpIndex, short helpState, HMMessageRecord& helpMessage, CPoint& localQDTip, CRect& localQDRect, short& balloonVariant) { long options; short theProc; short count; short oldResFile; VOLATILE(oldResFile); FailInfo fi; oldResFile = CurResFile(); Try(fi) { UseResFile(gApplicationRefNum); FailOSErr(HMGetIndHelpMsg(kHMDialogResType, helpResource, helpIndex,helpState, &options, localQDTip, localQDRect, &theProc, &balloonVariant, &helpMessage, &count)); fi.Success(); } else { UseResFile(oldResFile); fi.ReSignal(); } UseResFile(oldResFile); } // TApplication::GetHelpParameters //---------------------------------------------------------------------------------------- // TApplication::GetSleepRegion: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes RgnHandle TApplication::GetSleepRegion() { if (this->IsFrontProcess()) { // Compute based on where the mouse is right NOW CPoint globalMouse; GetMouse(globalMouse); LocalToGlobal(globalMouse); Boolean isSleepInvalid = false; // The help region is computed before the cursor rgn so that // the cursor region excludes the balloon shape if ((this->IsHelpRgnInvalid()) && (this->IsHelpEnabled())) { this->TrackHelp(globalMouse); isSleepInvalid = true; } if (this->IsCursorRgnInvalid()) { this->TrackCursor(globalMouse); isSleepInvalid = true; } if (isSleepInvalid) if (this->IsHelpEnabled()) SectRgn(fCursorRegion, fHelpRegion, fSleepRegion); else CopyRgn(fCursorRegion, fSleepRegion); // Ensure that the sleep region contains the mouse. PtAndRgn(globalMouse, fSleepRegion); return fSleepRegion; } else return NULL; } // TApplication::GetSleepRegion //---------------------------------------------------------------------------------------- // TApplication::GetEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TToolboxEvent* TApplication::GetEvent(short eventMask, long sleep, RgnHandle sleepRegion) { TToolboxEvent * returnEvent = NULL; #if qDebug --gRsrcCheck; if (gRsrcCheck <= 0) { CheckRsrcUsage(); gRsrcCheck = kRsrcCheckInterval; } #endif if (gIntenseDebugging && gReportEvent) { fprintf(stderr, "WaitNextEvent: sleep=0%d", sleep); // faceless driver bug fixed in MF 7.0 if (sleepRegion == NULL) fprintf(stderr, ", sleep region=NULL"); else { CRect bBox = (*sleepRegion)->rgnBBox; fprintf(stderr, ", sleep region = %s", (char*) bBox); } fprintf(stderr, "\n"); } #if qDebug if (gShowCursorRegion || gShowHelpRegion || gShowSleepRegion) { CGrafPort desktopPort; // Used for showing cursor region long ticks; // Used for showing cursor region GrafPtr savedPort; // Used for showing cursor region // Cursor region is in global coords. Need to create desktop port GetPort(&savedPort); if (qNeedsColorQD || gConfiguration.hasColorQD) OpenCPort(&desktopPort); else OpenPort((GrafPtr) & desktopPort); CopyRgn(GetGrayRgn(), desktopPort.visRgn); desktopPort.portRect = (*(desktopPort.visRgn))->rgnBBox; PenNormal(); PenMode(patXor); if (gShowCursorRegion) { PaintRgn(fCursorRegion); Delay(30, &ticks); PaintRgn(fCursorRegion); } if (gShowHelpRegion) { PaintRgn(fHelpRegion); Delay(30, &ticks); PaintRgn(fHelpRegion); } if (gShowSleepRegion) { PaintRgn(fSleepRegion); Delay(30, &ticks); PaintRgn(fSleepRegion); } sleep = 60; if (qNeedsColorQD || gConfiguration.hasColorQD) CloseCPort(&desktopPort); else ClosePort((GrafPtr) & desktopPort); SetPort(savedPort); } #endif // If we are in a nested event level than don't turn off the busy cursor since we are // probably in the middle of an idle or filter proc and don't want to turn on and off // the busy cursor each time it gets to service an event. if (fEventLevel <= 1) this->ActivateBusyCursor(false); // Turn off busy cursor while we're away. #if qPerform Boolean oldSetting = PerfMonitorEnabled(); #endif // SystemEvents aren't queued and will be lost if not retrieved when available. So we // ensure here that they are always retrieved by adding osMask. EventRecord anEvent; if (WaitNextEvent(((eventMask) | osMask), &anEvent, sleep, sleepRegion)) { Boolean oldObjectPerm = AllocateObjectsFromPerm(false); returnEvent = new TToolboxEvent; AllocateObjectsFromPerm(oldObjectPerm); returnEvent->IToolboxEvent(this, anEvent); } #if qPerform EnablePerfMonitor(oldSetting); #endif if (this->IsFrontProcess()) // If we're not in the background, then this->ActivateBusyCursor(true); // …enable the busy cursor mechanism. return returnEvent; } // TApplication::GetEvent //---------------------------------------------------------------------------------------- // TApplication::GetFrontWindow: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TWindow* TApplication::GetFrontWindow() { if (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!IsDeskAccessory(FrontWindow())) { CWMgrIterator iter; for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow()) { TWindow * aWindow = this->WMgrToWindow(aWinPtr); if ((aWindow) && (aWindow->IsShown()) && (!aWindow->fFloats)) return aWindow; } } return NULL; } // TApplication::GetFrontWindow //---------------------------------------------------------------------------------------- // TApplication::GetActiveWindow: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TWindow* TApplication::GetActiveWindow(Boolean floatersAreOkay) { if (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!IsDeskAccessory(FrontWindow())) { CWMgrIterator iter; for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow()) { TWindow * aWindow = this->WMgrToWindow(aWinPtr); if ((aWindow) && (aWindow->IsShown()) && (aWindow->IsActive())) { if (aWindow->fFloats) { if (floatersAreOkay) return aWindow; } else return aWindow; } } } return NULL; } // TApplication::GetActiveWindow //---------------------------------------------------------------------------------------- // TApplication::RetrieveAnEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TEvent* TApplication::RetrieveAnEvent() { TEvent* returnEvent = NULL; // Higher priority events are at the end of the list. CEventListIterator iter(fEventList); for (TEvent *itsEvent = iter.FirstEvent(); iter.More(); itsEvent = iter.NextEvent()) { if (itsEvent->IsReadyToExecute()) { returnEvent = itsEvent; break; } } if ((returnEvent) &&!returnEvent->IsRecurring()) fEventList->Delete(returnEvent); return returnEvent; } // TApplication::RetrieveAnEvent //---------------------------------------------------------------------------------------- // TApplication::NewToolboxWindow: //---------------------------------------------------------------------------------------- #pragma segment MAOpen #if defined(powerc) || defined(__powerc) #pragma options align=mac68k #endif struct WINDTemplate { CRect bounds; short procID; Boolean visible; Boolean filler1; Boolean goAway; Boolean filler2; long refcon; short itemsID; // only for DLOG resource }; #if defined(powerc) || defined(__powerc) #pragma options align=reset #endif typedef struct WINDTemplate WINDTemplate; typedef WINDTemplate* WINDTemplatePtr, **WINDTemplateHandle; WindowPtr TApplication::NewToolboxWindow(Ptr storage, short rsrcId, Boolean& isResizable, Boolean& isClosable) { // We force INVISIBLE in the WIND definition so the screen won't flash. WindowPtr aWMgrWindow; WINDTemplateHandle templateHandle; Boolean oldPerm; VOLATILE(oldPerm); // Even though the window is permanent, we allocate it under a temporary flag so that the // maximum memory is available. Quickdraw can blow up if it can't allocate a grafPort. oldPerm = PermAllocation(false); FailInfo fi; Try(fi) { templateHandle = (WINDTemplateHandle)GetResource('WIND', rsrcId); FailNILResource((Handle)templateHandle); MoveHHi((Handle)templateHandle); // in case it is locked by the ROM WINDTemplate & templateData = **templateHandle; templateData.visible = false; isClosable = templateData.goAway; isResizable = ((templateData.procID == documentProc) || (templateData.procID == zoomDocProc)); // If your own defProc is resizable, too, then after the call on NewToolboxWindow, set // isResizable true WindowPtr putWindowBehind = GetLastFloatingWindowPtr(); if (putWindowBehind == NULL) putWindowBehind = (WindowPtr) -1; if (qNeedsColorQD || gConfiguration.hasColorQD) aWMgrWindow = (WindowPtr)(GetNewCWindow(rsrcId, (Ptr)(storage), putWindowBehind)); else aWMgrWindow = GetNewWindow(rsrcId, (Ptr)(storage), putWindowBehind); FailNIL(aWMgrWindow); oldPerm = PermAllocation(oldPerm); fi.Success(); } else // Recover. Don't need the failure handler since we've set the perm allocation flag back. { // Make sure the perm allocation flag is set back to what it was // when we entered NewToolboxWindow. oldPerm = PermAllocation(oldPerm); fi.ReSignal(); } // Now we must make sure that the code reserve is still intact. if (!CheckReserve()) { aWMgrWindow = FreeIfWMgrWindow(aWMgrWindow, storage == NULL); Failure(memFullErr, 0); } return aWMgrWindow; } // TApplication::NewToolboxWindow //---------------------------------------------------------------------------------------- // TApplication::GetTarget: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TEventHandler* TApplication::GetTarget() { return fTarget; } // TApplication::GetTarget //---------------------------------------------------------------------------------------- // TApplication::HandleActivateEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleActivateEvent(TToolboxEvent* event) { TWindow * aWindow = this->WMgrToWindow((WindowPtr)(event->fEventRecord.message)); if (aWindow) { Boolean activate = ((event->fEventRecord.modifiers) & activeFlag) != 0; if (aWindow->fFloats) // ignore floaters { TWindow* frontWindow = this->GetFrontWindow(); // find frontmost non-floating window if (frontWindow) { aWindow = frontWindow; // (de)activate it instead of the floater HiliteWindow(aWindow->fWMgrWindow, activate); } } aWindow->Activate(activate); } else this->HandleAlienEvent(event); } // TApplication::HandleActivateEvent //---------------------------------------------------------------------------------------- // TApplication::HandleAlienEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleAlienEvent(TToolboxEvent* event) { CHandlerIterator iter(fHeadCohandler); for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler()) if (aHandler->DoCoHandlerEvent(event)) break; } // TApplication::HandleAlienEvent //---------------------------------------------------------------------------------------- // TApplication::HandleDiskEvent: //---------------------------------------------------------------------------------------- #pragma segment MADoCommand void TApplication::HandleDiskEvent(TToolboxEvent* event) { if (HiWord(event->fEventRecord.message) != noErr) { Point topLeft; SetPt(&topLeft,112,80); short err = DIBadMount(topLeft, event->fEventRecord.message); #if qDebugMsg if (err != noErr) fprintf(stderr, "error from DIBadMount is %d\n", err); #endif } } // TApplication::HandleDiskEvent //---------------------------------------------------------------------------------------- // TApplication::DoToolboxEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoToolboxEvent(TToolboxEvent* event) { #if qDebug if (gReportEvent && event) event->ReportEvent(); #endif this->DispatchEvent(event); } // TApplication::DoToolboxEvent //---------------------------------------------------------------------------------------- // TApplication::HandleFinderRequest: //---------------------------------------------------------------------------------------- #pragma segment MAFinder void TApplication::HandleFinderRequest() { #if !qNeedsAppleEventMgr TFile * aFile; short message; AppFile anAppFile; CommandNumber command; VOLATILE(aFile); VOLATILE(message); VOLATILE(anAppFile); VOLATILE(command); FailInfo outerFi; Try(outerFi) { // determine number of files and whether it's a print from finder request short theFileCount; CountAppFiles(&message, &theFileCount); Boolean finderPrinting = (message == appPrint); if (theFileCount == 0) { if (this->IsFrontProcess() && IsOptionKeyDown()) this->HandleMenuCommand(cOpen); else if (fLaunchWithNewDocument) this->HandleMenuCommand(cFinderNew); } else // it's an OPEN or PRINT of 1 or more existing files { if (finderPrinting) command = cFinderPrint; else command = cFinderOpen; TList * aFileList = NewList(); for (short i = 1; i <= theFileCount; ++i) { FailInfo fi; Try(fi) { aFile = this->DoMakeFile(command); GetAppFiles(i, &anAppFile); FailOSErr(aFile->SpecifyWithTrio(anAppFile.vRefNum, 0, (const CStr63 &) anAppFile.fName)); aFile->fFileType = anAppFile.fType; ClrAppFiles(i); aFileList->InsertLast(aFile); fi.Success(); } else // Recover { if (fi.error != noErr) { aFile = (TFile *)(FreeIfObject(aFile)); if (fi.message == 0) { gErrorParm3 = (CStr255)anAppFile.fName; if (command == cFinderPrint) fi.message = messagePrintFailed; else fi.message = messageOpenFailed; } this->ShowError(fi.error, fi.message); } } } if (finderPrinting) { TPDocCommand * aPDocCommand; aPDocCommand = new TPDocCommand; aPDocCommand->IPDocCommand(cFinderPrint, aFileList); this->PostCommand(aPDocCommand); } else { TODocCommand * anODocCommand; anODocCommand = new TODocCommand; anODocCommand->IODocCommand(cFinderOpen, aFileList); this->PostCommand(anODocCommand); } } outerFi.Success(); } else // Recover { if (outerFi.error != noErr) this->ShowError(outerFi.error, outerFi.message);// PollEvents' error handler not in place yet } #endif } // TApplication::HandleFinderRequest //---------------------------------------------------------------------------------------- // TApplication::HandleHighLevelEvent: Assume that the high level event received was an // Apple Event and process it. This will dispatch to us via MAGeneralDispatch. //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleHighLevelEvent(TToolboxEvent* event) { this->SetupTheMenus(); // Make sure that the menus are setup // correctly before we handle the event EventRecord anEventRecord = event->fEventRecord; OSErr theErr = AEProcessAppleEvent(&anEventRecord); if (theErr != errAEEventNotHandled) // If the event is one we don't handle, do nothing FailOSErr(theErr); } // TApplication::HandleHighLevelEvent //---------------------------------------------------------------------------------------- // TApplication::HandleKeyDownEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleKeyDownEvent(TToolboxEvent* event) { this->GetTarget()->KeyEventToComponents(event);// Find out what keys were _REALLY_ pressed if (event->IsCommandKeyPressed()) this->GetTarget()->HandleCommandKey(event); else this->GetTarget()->HandleKeyCommand(event); } // TApplication::HandleKeyDownEvent //---------------------------------------------------------------------------------------- // TApplication::HandleKeyUpEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleKeyUpEvent(TToolboxEvent* event) { // We don't think KeyUp events should affect the menus. event->fAffectsMenus = false; this->GetTarget()->KeyEventToComponents(event);// Find out what keys were _REALLY_ released this->GetTarget()->HandleKeyUp(event); } // TApplication::HandleKeyUpEvent //---------------------------------------------------------------------------------------- // TApplication::HandleMouseDown: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleMouseDown(TToolboxEvent* event) { WindowPtr aWMgrWindow; short whereMouseDown = FindWindow(event->fEventRecord.where, &aWMgrWindow); event->fClickCount = this->CountClicks(event, whereMouseDown); TWindow * aWindow = this->WMgrToWindow(aWMgrWindow); if ((whereMouseDown != inMenuBar) && this->InModalState() && (aWindow != (this->GetActiveWindow(kNoFloaters)))) { this->Beep(2); return; // exit(HandleMouseDown); } switch (whereMouseDown) { case inMenuBar: this->SetupTheMenus(); // gives application a chance to setup individual menu items SetCursor(&(qd.arrow)); this->MenuEvent(MenuSelect(event->fEventRecord.where)); break; case inSysWindow: { EventRecord anEventRecord = event->fEventRecord; SystemClick(&anEventRecord, aWMgrWindow); break; } default: // if a MacApp window was associated with the WindowPtr then let the window object decide // what to do with the mouse click if (aWindow) { if (aWindow->Focus()) // if we can't focus, we're in trouble { VPoint theMouse(event->fEventRecord.where); aWindow->SuperToLocal(theMouse); aWindow->HandleMouseDown(theMouse, event, gStdHysteresis); } #if qDebug else ProgramBreak("In TApplication::HandleMouseDown: couldn't focus on a window object!"); #endif } else this->HandleAlienEvent(event); break; } fLastUpTime = TickCount(); // Because the toolbox often eats mouseUpEvents remember the time on the way out for // double/ triple detection. } // TApplication::HandleMouseDown //---------------------------------------------------------------------------------------- // TApplication::HandleMouseUp: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleMouseUp(TToolboxEvent* event) { // now we _Really_ know what the last mouse up time is. // Remember time of last mouse up, in order to detect double/triple (multiple) clicks fLastUpTime = event->fEventRecord.when; WindowPtr aWMgrWindow; short whereMouseDown = FindWindow(event->fEventRecord.where, &aWMgrWindow); switch (whereMouseDown) { case inMenuBar: break; case inSysWindow: break; default: // if a MacApp window was associated with the WindowPtr then let the window object decide { TWindow * aWindow = this->WMgrToWindow(aWMgrWindow); // what to do with the mouse click if (aWindow) { if (aWindow->Focus()) // if we can't focus, we're in trouble { VPoint theMouse(event->fEventRecord.where); aWindow->SuperToLocal(theMouse); aWindow->HandleMouseUp(theMouse, event, gStdHysteresis); } #if qDebug else ProgramBreak("In TApplication::HandleMouseUp: couldn't focus on a window object!"); #endif } else this->HandleAlienEvent(event); break; } } } // TApplication::HandleMouseUp //---------------------------------------------------------------------------------------- // TApplication::HandleSystemEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleSystemEvent(TToolboxEvent* event) { switch (((unsigned long)(event->fEventRecord.message & osEvtMessageMask)) >> 24) { case suspendResumeMessage: { Boolean switchingIn = ((event->fEventRecord.message) & resumeFlag) != 0; Boolean convertClipboard = ((event->fEventRecord.message) & convertClipboardFlag) != 0; if (switchingIn) { // the Proces Manager may have activated the wrong window (if, when // we suspended earlier, we had non-floating window(s) that hide on suspend // such as the clipboard) so we augment what it did by activating the // right one! if (MAFrontWindow() != NULL) MADeactivateWindow(MAFrontWindow()); this->RegainControl(convertClipboard); TWindow * aWindow = this->GetFrontWindow(); if (aWindow) MAActivateWindow(aWindow->fWMgrWindow); } else { // When switching out, after having hid windows that get hid on suspend in // AboutToLoseControl, we need to ensure that our idea about the front // window and the Process Mgr's idea about the front window are the same. // (note that we do the second half of the work when we get the resume // event). WindowPtr theFrontWindow = MAFrontWindow();// remember the front window this->AboutToLoseControl(convertClipboard);// might hide windows… TWindow * aWindow = this->GetActiveWindow(false); if (aWindow) MADeactivateWindow(aWindow->fWMgrWindow); } if (!(qNeedsProcessMgr || gConfiguration.hasProcessMgr)) fInBackground =!switchingIn; this->InvalidateMouseRegions(); } break; case mouseMovedMessage: event->fAffectsMenus = false; // We don't think mouse tracking usually // bothers the menus. We got the mouse // moved event because the mouse strayed // outside of fSleepRegion. It may or may // not have strayed outside of the other // mouse regions. We'll only invalidate // them here (if necessary) because that // way we can defer computing them for as // long as possible. if (!PtInRgn(event->fEventRecord.where, fCursorRegion)) this->InvalidateCursorRgn(); if (!PtInRgn(event->fEventRecord.where, fHelpRegion)) this->InvalidateHelpRgn(); break; default: if (gIntenseDebugging) fprintf(stderr, "in TApplication.HandleSystemEvent: got unrecognized event\n"); break; } } // TApplication::HandleSystemEvent //---------------------------------------------------------------------------------------- // TApplication::HandleToolboxEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleToolboxEvent(TToolboxEvent* event) { FailInfo fi; Try(fi) { Boolean proceed = true; TBehavior* aBehavior = this->GetFirstEnabledBehavior(); if (aBehavior) proceed = !aBehavior->DoToolboxEvent(event); if (proceed) this->DoToolboxEvent(event); fi.Success(); } else // Recover { this->DidEvent(event); fi.ReSignal(); } this->DidEvent(event); } // TApplication::HandleToolboxEvent //---------------------------------------------------------------------------------------- // TApplication::HandleUpdateEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleUpdateEvent(TToolboxEvent* event) { // We don't think that update events should affect menus. event->fAffectsMenus = false; TWindow * aWindow = this->WMgrToWindow((WindowPtr)event->fEventRecord.message); if (aWindow) aWindow->Update(); else this->HandleAlienEvent(event); } // TApplication::HandleUpdateEvent //---------------------------------------------------------------------------------------- // TApplication::Idle: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::Idle(IdlePhase phase) { FailInfo fi; Try(fi) { if (phase == idleBegin) { if (!gInFilter && MemSpaceIsLow()) this->SpaceIsLowAlert(); else fNextSpaceMessage = TickCount(); } // Create a new block for failure handling { CHandlerIterator iter(fHeadCohandler); for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler()) aHandler->HandleIdle(phase); } #if qDebug Assertion(this->GetTarget() != NULL, "GetTarget != NULL"); #endif // Create a new block for failure handling { CHandlerIterator iter(this->GetTarget()); for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler()) aHandler->HandleIdle(phase); } fi.Success(); } else // Recover { gInhibitNestedHandling = true; // Don't want to come back into Idle From // alert filters or other strange places fi.ReSignal(); } } // TApplication::Idle //---------------------------------------------------------------------------------------- // TApplication::GetWaitTicks: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes long TApplication::GetWaitTicks(Boolean allowApplicationToSleep) { const short kMaxSleep = 60; // max sleep in foreground so MultiFinder // gives time to non-desk accessory drivers long returnValue = 0; if (allowApplicationToSleep) { long compositeTicks = kMaxIdleTime; // Check the cohandler chain first. Add new block for failure handling { CHandlerIterator iter(fHeadCohandler); for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler()) compositeTicks = MinMax(0, aHandler->NextIdle() - TickCount(), compositeTicks); } #if qDebug Assertion(this->GetTarget() != NULL, "GetTarget != NULL"); #endif // now run through the target chain. Add new block for failure handling { CHandlerIterator iter(this->GetTarget()); for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler()) compositeTicks = MinMax(0, aHandler->NextIdle() - TickCount(), compositeTicks); } // faceless driver bug in M.F fixed in process manager if (qNeedsProcessMgr || gConfiguration.hasProcessMgr) returnValue = compositeTicks; else if ((compositeTicks > kMaxSleep) && this->IsFrontProcess()) { if (gIntenseDebugging && gReportEvent) fprintf(stderr, "IN TApplication.GetWaitTicks: clipped to MaxSleep=%d\n", kMaxSleep); returnValue = Min(compositeTicks, kMaxSleep); } } return returnValue; } // TApplication::GetWaitTicks //---------------------------------------------------------------------------------------- // TApplication::InModalState: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::InModalState() { WindowPtr aWindowPtr = FrontWindow(); // in case the front window is an alert or something if ((this->WMgrToWindow(aWindowPtr) == NULL) && (aWindowPtr)) switch (GetWindowVariant(aWindowPtr)) { case dBoxProc: case plainDBox: case altDBoxProc: return true; default: return false; } else { TWindow * aWindow = this->GetActiveWindow(kNoFloaters); return (aWindow && aWindow->IsInModalState()); } } // TApplication::InModalState //---------------------------------------------------------------------------------------- // TApplication::InstallCohandler: //---------------------------------------------------------------------------------------- #pragma segment MANonRes void TApplication::InstallCohandler(TEventHandler* aCohandler, Boolean addIt) { if (addIt) fHeadCohandler = aCohandler->AddHandler(fHeadCohandler); else fHeadCohandler = aCohandler->RemoveHandler(fHeadCohandler); } // TApplication::InstallCohandler //---------------------------------------------------------------------------------------- // TApplication::IsDeskAccessory: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::IsDeskAccessory(WindowPtr aWMgrWindow) { return (!(qNeedsProcessMgr || gConfiguration.hasProcessMgr) && ((aWMgrWindow) && (((WindowPeek)aWMgrWindow)->windowKind < 0))); } // TApplication::IsDeskAccessory //---------------------------------------------------------------------------------------- // TApplication::IsFrontProcess: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::IsFrontProcess() { if (qNeedsProcessMgr || gConfiguration.hasProcessMgr) { ProcessSerialNumber aPSN; ProcessSerialNumber applicationPSN; Boolean result; FailOSErr(GetFrontProcess(&aPSN)); applicationPSN = fProcessNumber; FailOSErr(SameProcess(&aPSN, &applicationPSN, &result)); return result; } else return !fInBackground; } // TApplication::IsFrontProcess //---------------------------------------------------------------------------------------- // TApplication::MakeFrontProcess: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::MakeFrontProcess() { if (!this->IsFrontProcess()) { ProcessSerialNumber aPSN = fProcessNumber; FailOSErr(SetFrontProcess(&aPSN)); } } // TApplication::MakeFrontProcess //---------------------------------------------------------------------------------------- // TApplication::IsHelpEnabled: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::IsHelpEnabled() { if (qNeedsHelpMgr || gConfiguration.hasHelpMgr) return HMGetBalloons(); else return false; } // TApplication::IsHelpEnabled //---------------------------------------------------------------------------------------- // TApplication::InvalidateMouseRegions: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::InvalidateMouseRegions() { this->InvalidateCursorRgn(); this->InvalidateHelpRgn(); } // TApplication::InvalidateMouseRegions //---------------------------------------------------------------------------------------- // TApplication::InvalidateCursorRgn: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::InvalidateCursorRgn() { if (fCursorRegion) SetEmptyRgn(fCursorRegion); // Make sure it gets changed back } // TApplication::InvalidateCursorRgn //---------------------------------------------------------------------------------------- // TApplication::InvalidateHelpRgn: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::InvalidateHelpRgn() { if (fHelpRegion) SetEmptyRgn(fHelpRegion); // Make sure it gets changed back if (qNeedsHelpMgr || gConfiguration.hasHelpMgr) if (this->IsFrontProcess() && HMIsBalloon()) { OSErr err = HMRemoveBalloon(); if (err != hmNoBalloonUp) FailOSErr(err); } } // TApplication::InvalidateHelpRgn //---------------------------------------------------------------------------------------- // TApplication::InvalidateFocus: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::InvalidateFocus() { if (gFocusedView) gFocusedView->InvalidateFocus(); } // TApplication::InvalidateFocus //---------------------------------------------------------------------------------------- // TApplication::IsCursorRgnInvalid: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::IsCursorRgnInvalid() { // The cursor is normally tracked via MouseMoved events. But for those with special // needs fAlwaysTrackCursor can come to the rescue. return (EmptyRgn(fCursorRegion) || fAlwaysTrackCursor); } // TApplication::IsCursorRgnInvalid //---------------------------------------------------------------------------------------- // TApplication::IsHelpRgnInvalid: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::IsHelpRgnInvalid() { return EmptyRgn(fHelpRegion); } // TApplication::IsHelpRgnInvalid //---------------------------------------------------------------------------------------- // TApplication::KeyEventToComponents: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::KeyEventToComponents(TToolboxEvent* event) // See Tech Note #263 for the reason for this abomination { const short kMaskModifier = 0xFE00; // need to strip command key from Modifiers const long kMaskASCII1 = 0x000000FF; // get key from KeyTranslate return const long kMaskASCII2 = 0x00FF0000; // get key from KeyTranslate return const short kUpKeyMask = 0x0080; Inherited::KeyEventToComponents(event); // Get default translation, if any if ((event->fEventRecord.what == keyDown) || (event->fEventRecord.what == keyUp) || (event->fEventRecord.what == autoKey)) { // Now see if the command key is down. If it is, get the correct ASCII translation by // masking the command key out and re-translating because the command key will // mask the shift modifier. if (event->IsCommandKeyPressed()) { // set the upkey bit so KeyTranslate doesn't do special deadkey processing // See IM-V pp. 195 short keyCodeParameter = ((((event->fEventRecord.modifiers) & kMaskModifier) | event->fKeyCode) | kUpKeyMask); long state = 0; // Get the correct keytable pointer. We don't want to grope the system unnecessarily so // use the script managers improvements if they're there. Ptr keyTransTable; #if qPowerPC keyTransTable = (Ptr)(GetScriptManagerVariable(smKCHRCache)); #else if (qNeedsSystem7 || gConfiguration.systemVersion >= 0x700) keyTransTable = (Ptr)(GetScriptManagerVariable(smKCHRCache)); else { // !!! Delete this record for 7.0 only operation. This is really a private record so // _DON'T_ use any other fields! struct MAExpandMemRec { short emVersion; // version of expanded memory long emSize; // length of em long emIntlGlobals; // international globals pointer long emKeyDeadState; // Key1Trans, Key2Trans dead state Ptr emKeyCache; // KCHR keyboard cache long emInternationalDefinition;// Reserved for Intl Boolean emFirstKeyboard; // flag byte Boolean emAlign; // long-align until we need this storage long emItlCache[4]; // bytes in cache Boolean emItlNeedUnlock; // for pack6 Boolean emItlDirectGetIntl; // for pack6 unsigned char emFiller[22]; // Reserved room }; typedef struct MAExpandMemRec MAExpandMemRec; typedef MAExpandMemRec* MAExpandMemRecPtr, ** MAExpandMemRecHandle; // Fake handle. the lomem address is a pointer to the table enum { ExpandMem = 0x2B6 // a holdover from SysEqu.h }; keyTransTable = (Ptr)((*(MAExpandMemRecHandle)(ExpandMem))->emKeyCache); } #endif long keyInfo = KeyTranslate(keyTransTable, keyCodeParameter, &state); event->fCharacter = (unsigned char)(((keyInfo) & kMaskASCII1)); if (event->fCharacter == (unsigned char)(0)) event->fCharacter = (unsigned char)((keyInfo >> kMaskASCII2) & 16); } } } // TApplication::KeyEventToComponents //---------------------------------------------------------------------------------------- // TApplication::KindOfDocument: //---------------------------------------------------------------------------------------- #pragma segment MAOpen CommandNumber TApplication::KindOfDocument(CommandNumber itsCommandNumber, TFile*) { return itsCommandNumber; } // TApplication::KindOfDocument //---------------------------------------------------------------------------------------- // TApplication::MainEventLoop: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes // must be in the main segment void TApplication::MainEventLoop() { fIdlePhase = idleBegin; while (!fDone) this->PollEvent(kAllowApplicationToSleep); } // TApplication::MainEventLoop //---------------------------------------------------------------------------------------- // TApplication::DoLaunchClipboard: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TApplication::DoLaunchClipboard() { if (gClipboardMgr) { gClipboardMgr->Launch(); // Launch after segments are unloaded // since reading the scrap may be piggy } } // TApplication::DoLaunchClipboard //---------------------------------------------------------------------------------------- // TApplication::MakeViewForAlienClipboard: //---------------------------------------------------------------------------------------- #pragma segment MAClipboard TView* TApplication::MakeViewForAlienClipboard() { return NULL; // use defaults } // TApplication::MakeViewForAlienClipboard //---------------------------------------------------------------------------------------- // TApplication::MenuEvent: //---------------------------------------------------------------------------------------- #pragma segment MASelCommand void TApplication::MenuEvent(long menuItem) { short theMenuNumber = HiWord(menuItem); short theItemNumber = LoWord(menuItem); if (theMenuNumber) { CommandNumber command = CommandFromMenuItem(theMenuNumber, theItemNumber); VOLATILE(command); #if qDebugMsg if (command == cCantUndo) { fprintf(stderr, "Command number %d is reserved for MacApp.\n", cCantUndo); ProgramBreak("Use of reserved command number."); } if (gReportMenuChoices && (command > 0)) fprintf(stderr, "Menu Choice Command Number == %d\n", command); #endif if ((command < 0) && (theMenuNumber == mApple)) { CStr255 deskAccName; GetMenuItemText(MAGetMenuHandle(mApple), theItemNumber, deskAccName); this->OpenDeskAccessory(deskAccName); } else if ((command < cEditBase) || (command > cEditLast) || (!SystemEdit((short)(command - cEditBase)))) { FailInfo fi; Try(fi) { if (fSysWindowActive) this->ActivateBusyCursor(true); this->GetTarget()->HandleMenuCommand(command); if (fSysWindowActive) this->ActivateBusyCursor(false); fi.Success(); } else // Recover { if (fSysWindowActive) this->ActivateBusyCursor(false); FailNewMessage(fi.error, fi.message, BuildMessage((short)command, messageCommandError)); fi.ReSignal(); } } } } // TApplication::MenuEvent //---------------------------------------------------------------------------------------- // TApplication::OpenDeskAccessory: //---------------------------------------------------------------------------------------- void TApplication::OpenDeskAccessory(const CStr255& deskAccName) { #if !qPowerPC // then go ahead and open it; it's in a separate process if (qNeedsProcessMgr || gConfiguration.hasProcessMgr) { #endif GrafPtr savedPort; GetPort(&savedPort); OpenDeskAcc(deskAccName); SetPort(savedPort); #if !qPowerPC } else { GrafPtr savedPort; Boolean oldPerm; Boolean ourHeap; Handle drvrH; ResType theType; short theID; Str255 theName; short aRefNum; VOLATILE(aRefNum); FailInfo fi; Try(fi) { aRefNum = 0; // Make sure failure handler works. // Attempt to load the DA into memory. If 'deskAccName' refers to another app // rather than a real desk acc, then GetNamedResource returns a faked up // handle courtesy of MultiFinder . We open the DA with permanent allocation // so as to ensure that we don't take space from our code segments. oldPerm = PermAllocation(true); drvrH = GetNamedResource('DRVR', deskAccName); PermAllocation(oldPerm); FailNILResource(drvrH); // Either there wasn't enough memory to // load the DA, or something is seriously // wrong. // At this point if we are really opening a DA we know it fits in memory. GetResInfo(drvrH, &theID, &theType, theName);// If it's a not a real DA then this // will generate a ResError. // Find out which zone it lives in, or if option key is down. ourHeap = ((HandleZone(drvrH) == ApplicationZone()) || (this->IsFrontProcess() && IsOptionKeyDown())); if ((ResError() != noErr) || // If it's a MultiFinder fake DA, IsOpen(theID) || // …or if the DA is already open, (!ourHeap)) // …or if it's not going in our heap { oldPerm = PermAllocation(true); // In case we guess wrong GetPort(&savedPort); aRefNum = OpenDeskAcc(deskAccName);// …then go ahead and open it. SetPort(savedPort); PermAllocation(oldPerm); } else { // If we get this far, we know we have a real DA and it's going into our // heap. Open it, but them make sure we have enough memory to continue // running. FailSpaceIsLow(); // In case we're already low on mem. oldPerm = PermAllocation(true); // If the pig wants to wallow GetPort(&savedPort); aRefNum = OpenDeskAcc(deskAccName);// Use temporary allocation. SetPort(savedPort); PermAllocation(oldPerm); FailSpaceIsLow(); // Fail if not enough memory left. FailNIL(*drvrH); // …or if the driver was purged to // …satisfy a code space requirement. } fi.Success(); } else // Recover { if (aRefNum) CloseDeskAcc(aRefNum); if (fi.message == 0) { gErrorParm3 = deskAccName; // Get rid of leading NULL character if (gErrorParm3[1] == 0) gErrorParm3.Delete(1, 1); } FailNewMessage(fi.error, fi.message, messageOpenFailed); fi.ReSignal(); } } #endif } // TApplication::OpenDeskAccessory //---------------------------------------------------------------------------------------- // TApplication::OpenNew: //---------------------------------------------------------------------------------------- #pragma segment MAOpen TDocument* TApplication::OpenNew(CommandNumber itsCommandNumber) { TDocument* aDocument = NULL; VOLATILE(aDocument); FailInfo fi; Try(fi) { FailNIL(aDocument = this->DoMakeDocument(this->KindOfDocument(itsCommandNumber, NULL), NULL)); aDocument->DoInitialState(); aDocument->DoMakeViews(kForDisplay); CStr255 newTitle; aDocument->UntitledName(newTitle); aDocument->SetTitle(newTitle); FailSpaceIsLow(); // Fail if document leaves us with no room // Don't attempt to show the windows until we're sure we won't fail aDocument->DoPostMakeViews(kForDisplay); fi.Success(); } else // Recover { if (aDocument) aDocument = (TDocument *)(FreeIfObject(aDocument)); // The document will free the file FailNewMessage(fi.error, fi.message, messageNewFailed); fi.ReSignal(); } return aDocument; } // TApplication::OpenNew //---------------------------------------------------------------------------------------- // TApplication::OpenOld: //---------------------------------------------------------------------------------------- #pragma segment MAOpen TDocument* TApplication::OpenOld(CommandNumber itsOpenCommand, TList* aFileList) { TDocument* aDocument = NULL; TFile* aFile = NULL; TFile* aNewFile = NULL; Size oldCodeReserve; Size oldMemReserve; OSErr savedError = 0; long savedMessage = 0; VOLATILE(aDocument); VOLATILE(aFile); VOLATILE(aNewFile); VOLATILE(oldCodeReserve); VOLATILE(oldMemReserve); VOLATILE(savedError); VOLATILE(savedMessage); { // Put iterator in a separate block so that it will go out of scope before the end of the method. // We don't want the iterator's failure handler to be invoked, because its stack ptr is munged. // If an error occurs, we'll just save it and ReSignal it after the iterator is gone. CObjectIterator iter(aFileList); for (aFile = (TFile *)iter.FirstObject(); iter.More() && !savedError; aFile = (TFile *)iter.NextObject()) { // reset aDocument and aNewFile so that they no longer refer to items from the // last go round (important in case we fail downstream)… aDocument = NULL; aNewFile = NULL; CStr63 fileName; aFile->GetName(fileName); // If failure occurs the file may already be // freed so we will save the name just in // case. aFileList->Delete(aFile); // ReadStationery if successful will dispose // of the file for us so if failure occurs // this had better not be in the file list. FailInfo fi; Try(fi) { // Set reserve down a little to ensure that we can open existing documents GetReserveSize(oldCodeReserve, oldMemReserve); SetReserveSize(oldCodeReserve, oldMemReserve / 2); TDocument * otherDoc = this->FindDocument(aFile); Boolean isStationery = aFile->IsStationery(); if (otherDoc && !isStationery) { otherDoc->OpenAgain(itsOpenCommand, aDocument); aFile = (TFile*)FreeIfObject(aFile); SetReserveSize(oldCodeReserve, oldMemReserve); } else if (this->CanOpenDocument(itsOpenCommand, aFile)) { TFile* fileOwnedByDoc = aFile; aFile = NULL; FailNIL(aDocument = this->DoMakeDocument(this->KindOfDocument(itsOpenCommand, fileOwnedByDoc), fileOwnedByDoc)); if (!isStationery) aDocument->ReadDocument(kForDisplay); else { aNewFile = this->DoMakeFile(itsOpenCommand); aDocument->ReadStationery(aNewFile); aFile = NULL; // This file has already been freed by ReadStationery. aNewFile = NULL; // Clear our reference so that if we fail // we don't try to free this file twice. } aDocument->DoMakeViews(kForDisplay); if (isStationery) { CStr255 newTitle; aDocument->UntitledName(newTitle); aDocument->SetTitle(newTitle); } FailSpaceIsLow(); // Fail if the document leaves us with no // memory // Set the reserve back to where it was SetReserveSize(oldCodeReserve, oldMemReserve); // Don't attempt to show the windows until we're sure we won't fail aDocument->DoPostMakeViews(kForDisplay); } else Failure(errNotMyType, 0); fi.Success(); } else // Recover { if (fi.message == 0) gErrorParm3 = fileName; // ok, this gets tricky but here is how it works. If we have a document then // we know that we failed after DoMakeDocument and aFile will be freed by // freeing the document or it has already been freed as a side effect of // reading the stationery. If we don't have a document then we need to free // aFile ourselves. if (aDocument) aDocument = (TDocument *)(FreeIfObject(aDocument)); // The document will free the file else aFile = (TFile*)FreeIfObject(aFile); // otherwise its our responsibility aNewFile = (TFile*)FreeIfObject(aNewFile); // If we successfully read the // stationery then aNewFile will be NULL // Set the reserve back to where it was SetReserveSize(oldCodeReserve, oldMemReserve); // Don't want to fail here, because the CObjectIterator (with its embedded FailInfo) is // still in scope. Instead, save the error info until after the iterator has self-destructed. // FailNewMessage(fi.error, fi.message, messageOpenFailed); savedError = fi.error; savedMessage = fi.message; if (!savedMessage) savedMessage = messageOpenFailed; } } } // iterator will self-destruct now if (savedError != noErr) // Do we need to ReSignal a failure? { // signal the failure Failure(savedError, savedMessage); } return aDocument; } // TApplication::OpenOld //---------------------------------------------------------------------------------------- // TApplication::ProcessEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::ProcessEvent(TEvent* event) { if (qDebug &&!event) ProgramBreak("NULL passed to TApplication::ProcessEvent"); else if (qDebug && (!IsObject(event))) // since it's possible to have passed in a // freed undoable command allocated in a // global variable (due to pilot error) { VerboseIsObject(event); ProgramBreak("bogus object passed to TApplication::ProcessEvent"); } else { #if qDebug if (gIntenseDebugging) { MAName aMAName; event->GetClassName(aMAName); fprintf(stderr, "The Event to process: %s\n", (char*)aMAName); } #endif } if (event) event->Process(); } // TApplication::ProcessEvent //---------------------------------------------------------------------------------------- // TApplication::PollEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::PollEvent(Boolean allowApplicationToSleep) { Boolean didAllowApplicationToSleep = fAllowApplicationToSleep; VOLATILE(didAllowApplicationToSleep); fAllowApplicationToSleep = allowApplicationToSleep; ++fEventLevel; #if qDebugMsg if (!this->GetTarget()) ProgramBreak("Serious Error!! in TApplication.PollEvent: target == NULL"); #endif FailInfo fi; Try(fi) { TEvent * retrievedEvent = this->RetrieveAnEvent(); if (retrievedEvent) this->ProcessEvent(retrievedEvent); // The desk scrap may have been changed by use of command-X or command-C in desk accessories. if (fSysWindowActive) { gClipboardMgr->CheckDeskScrap(); this->InvalidateFocus(); } fi.Success(); --fEventLevel; if (fEventLevel == 0) gInhibitNestedHandling = false; // All clear } else // Recover { #if qDebugMsg fprintf(stderr, "\n"); // add a blank line after all the messages from Failure #endif fAllowApplicationToSleep = didAllowApplicationToSleep; --fEventLevel; if (fEventLevel == 0) { if (fi.error != noErr) { #if !qPowerPC UnloadAllSegments(); #endif this->ShowError(fi.error, fi.message); } InvalidateMenus(); } else fi.ReSignal(); } fAllowApplicationToSleep = didAllowApplicationToSleep; } // TApplication::PollEvent //---------------------------------------------------------------------------------------- // TApplication::PollToolboxEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes Boolean TApplication::PollToolboxEvent(Boolean allowApplicationToSleep) { long waitTicks = 0; RgnHandle sleepRegion = NULL; EventRecord theEvent; if (!EventAvail(fMainEventMask, &theEvent)) // We'll only sleep if there aren't any // waiting Events (keystrokes, mousedowns) { this->SetupTheMenus(); // ensure that an event didn't come in during SetupTheMenus if (!EventAvail(fMainEventMask, &theEvent)) { sleepRegion = this->GetSleepRegion(); // ensure that an event didn't come in during GetSleepRegion if (!EventAvail(fMainEventMask, &theEvent)) waitTicks = this->GetWaitTicks(allowApplicationToSleep);// calc last so it's most accurate else sleepRegion = NULL; } } HiliteMenu(0); // Cleanup any menu titles left hilited. // Done here so titles stay hilited until // synchronous actions are performed. TToolboxEvent * event = this->GetEvent(fMainEventMask, waitTicks, sleepRegion); Boolean gotAnEvent = (event != NULL); if (gotAnEvent) { // GetEvent returned an event (work to do). If we were idling before then we must // keep the calls balanced with an IdleEnd to because we are no longer idling if (fIdlePhase == idleContinue) { this->Idle(idleEnd); fIdlePhase = idleBegin; } // Rather than posting the event where it would have to be sorted and compete with // other commands we will process the command directly. this->ProcessEvent(event); // The desk scrap may have been changed by use of command-X or command-C in desk accessories. if (fSysWindowActive) { gClipboardMgr->CheckDeskScrap(); this->InvalidateFocus(); } } else // Woke up with no event available. Truly idle { this->Idle(fIdlePhase); fIdlePhase = idleContinue; } #if qDebug gErrorParm3 = "?????"; // to prevent anyone from using old values #endif return gotAnEvent; } // TApplication::PollToolboxEvent //---------------------------------------------------------------------------------------- // TApplication::PostAnEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::PostAnEvent(TEvent* event) // Override { FailInfo fi; Try(fi) { if (event->IsReadyToPost()) fEventList->Insert(event); // inserts event ordered the list fi.Success(); } else { if (event->ShouldFreeOnCompletion()) event = (TEvent *)FreeIfObject(event); fi.ReSignal(); } } // TApplication::PostAnEvent //---------------------------------------------------------------------------------------- // TApplication::PostCommand: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::PostCommand(TCommand* command)// Override { if (command) this->PostAnEvent(command); } // TApplication::PostCommand //---------------------------------------------------------------------------------------- // TApplication::PostPendingReplyCommand: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::PostPendingReplyCommand(TCommand* command) { fPendingReplyList->Insert(command); } // TApplication::PostPendingReplyCommand //---------------------------------------------------------------------------------------- // TApplication::DidEvent: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DidEvent(TToolboxEvent* event) { if (event && event->fAffectsMenus) InvalidateMenus(); Boolean perm = PermAllocation(false); #if qDebug if (perm) ProgramBreak("The permanent flag was left true."); #endif // See if a system window has been activated or deactivated. if (!(qNeedsProcessMgr || gConfiguration.hasProcessMgr) && (fSysWindowActive != this->IsDeskAccessory(FrontWindow()))) { fSysWindowActive =!fSysWindowActive; if (fSysWindowActive) // deactivating to sys window { this->AboutToLoseControl(true); InvalidateMenuBar(); } else // coming back from sys window this->RegainControl(true); } if (event && (event->ShouldFreeOnCompletion())) event = (TToolboxEvent *)FreeIfObject(event); } // TApplication::DidEvent //---------------------------------------------------------------------------------------- // TApplication::PrintDocuments: //---------------------------------------------------------------------------------------- #pragma segment MAFinder void TApplication::PrintDocuments(TList* aFileList) { TDocument* aDocument = NULL; TFile* aFile = NULL; VOLATILE(aDocument); VOLATILE(aFile); gFinderPrintingProceed = true; // set in TStdPrintHandler::DoPrintCommand // If we have previously done a finder print we need to toss the old print information // or we won't ask the user for some new stuff. gFinderHPrint = DisposeIfHandle(gFinderHPrint); CObjectIterator iter(aFileList); for (aFile = (TFile *)iter.FirstObject(); iter.More(); aFile = (TFile *)iter.NextObject()) { if (gFinderPrintingProceed) { FailInfo fi; Try(fi) { FailNIL(aDocument = this->DoMakeDocument(this->KindOfDocument(cFinderPrint, aFile), aFile)); aDocument->ReadDocument(kForPrinting); aDocument->DoMakeViews(kForPrinting); aDocument->DoPostMakeViews(kForPrinting); aDocument->HandleMenuCommand(cFinderPrint); fi.Success(); } else // Recover { if (aDocument) { // If there is a document then it will have a reference to aFile and // will free it when it is freed. Therefore we need to remove it from // the list so that when the file list is freed we don't attempt to // free it twice. aFileList->Delete(aFile); aDocument = (TDocument *)FreeIfObject(aDocument); } fi.ReSignal(); } aFileList->Delete(aFile); aDocument = (TDocument *)FreeIfObject(aDocument); } else break; // The user canceled printing } } // TApplication::PrintDocuments //---------------------------------------------------------------------------------------- // TApplication::RegainControl: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::RegainControl(Boolean checkClipboard) { #if qNeedsVU Inherited::RegainControl(checkClipboard); #endif this->ActivateBusyCursor(true); gClipboardMgr->RegainControl(checkClipboard); // Let all windows know that we're regaining control - e.g. so floaters can show themselves CWMgrIterator iter; for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow()) { TWindow * aWindow = this->WMgrToWindow(aWinPtr); if (aWindow) aWindow->RegainControl(); } } // TApplication::RegainControl //---------------------------------------------------------------------------------------- // TApplication::Run: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes // must be in the main segment void TApplication::Run() { #if !qPowerPC UnloadAllSegments(); #endif FailSpaceIsLow(); // make sure we have enough memory to continue gInitialized = true; // was set false at static init time this->DoLaunchClipboard(); // I know this looks funny but this does cover the case where we are built for system // 6.0 but are running on system 7.0. In that case we still don't want to // HandleFinderRequest. However if we are built for system 7.0 then this code will be // conditionally compiled out if (!gConfiguration.hasAppleEventMgr) { #if !qPowerPC UnloadAllSegments(); #endif this->HandleFinderRequest(); } #if !qPowerPC UnloadAllSegments(); #endif fEventLevel = 0; // Indicate outermost level this->MainEventLoop(); // runs until a quit command this->AboutToLoseControl(true); #if qDebug // See if previous max. resource usage has been exceeded by the termination code and // resources. CheckRsrcUsage(); // We must call CleanupMacApp here; if we wait to fall thru to the end of the main // program, A5 has been invalidated and we can't refer to any globals. CleanupMacApp(); #endif } // TApplication::Run //---------------------------------------------------------------------------------------- // TApplication::SelectToolboxWindow: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::SelectToolboxWindow(WindowPtr windowToSelect) { WindowPtr currentFrontWindow = NULL; WindowPtr lastFloatingWindow = NULL; Boolean isFloatingWindow = IsFloatWindow(windowToSelect); if (isFloatingWindow) { currentFrontWindow = GetFirstFloatingWindowPtr(); } else { currentFrontWindow = MAFrontWindow(); lastFloatingWindow = GetLastFloatingWindowPtr(); } // Be fast (and lazy) and do nothing if we don’t have to. if (currentFrontWindow != windowToSelect) { // Selecting floating windows are easy, since they’re always active if (isFloatingWindow) BringToFront(windowToSelect); else { // If there are no floating windows, we can call SelectWindow like the good ol’ days if (lastFloatingWindow == NULL) SelectWindow(windowToSelect); else { // Deactivate the window currently in front. MADeactivateWindow(currentFrontWindow); // Bring it behind the last floating window if it is not modal and activate it. // Note that Inside Mac 1 states that you need to call PaintOne() and CalcVis() on a // window if you are using SendBehind() to bring it closer to the front. With System 7, // this is no longer necessary. if (!(IsModalWindow(windowToSelect))) SendBehind(windowToSelect,lastFloatingWindow); else BringToFront(windowToSelect); MAActivateWindow(windowToSelect); } } } // Make sure previous mouse clicks are not considered part of a multi-click. fLastClickPart = inDesk; } //---------------------------------------------------------------------------------------- // TApplication::SetTarget: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::SetTarget(TEventHandler* newTarget) { if (newTarget == NULL) { newTarget = this; #if qDebug ProgramBreak("In TApplication.SetTarget… you're setting the global target to NULL!"); #endif } if (newTarget != fTarget) { fTarget->ResignedTarget(); fTarget = newTarget; fTarget->BecameTarget(); this->InvalidateMouseRegions(); } } // TApplication::SetTarget //---------------------------------------------------------------------------------------- // TApplication::SetUndoText: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::SetUndoText(Boolean cmdDone, CommandNumber aCommandNumber) { if ((fUndoState != cmdDone) || (fUndoCommand != aCommandNumber)) { short newMenuState; if (aCommandNumber == cCantUndo) newMenuState = bzCantUndo; else if (cmdDone) newMenuState = bzUndo; else newMenuState = bzRedo; CStr255 undoName; GetIndString(undoName, kIDBuzzString, newMenuState); short preCmdName; short constChars; if (ParseTitleTemplate(undoName, preCmdName, constChars)) { CStr255 cmdName = gEmptyString; if ((aCommandNumber != cNoCommand) && (aCommandNumber != cCantUndo)) CommandToName(aCommandNumber, cmdName); SubstituteInTitle(undoName, cmdName, preCmdName, constChars); } SetCommandName(cUndo, undoName); fUndoState = cmdDone; fUndoCommand = aCommandNumber; } } // TApplication::SetUndoText //---------------------------------------------------------------------------------------- // TApplication::SetupTheMenus: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::SetupTheMenus() { if (this->IsFrontProcess() && (MenusHavePendingUpdate())) { gMenuBarManager->Reset(); // reset the preferred menubar PerformMenuSetup(&DoSetupTheMenus, (void *)kNoStaticLink); gMenuBarManager->InstallPreferredMenus(); if (MenusHavePendingUpdate()) { // Add the debugger menu if (qDebug || qPerform) AddMenuBar(kMBarDebug, false); // Recurse to get the menus correctly setup this->SetupTheMenus(); } } } // TApplication::SetupTheMenus //---------------------------------------------------------------------------------------- // TApplication::GetStandardFileParameters: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TApplication::GetStandardFileParameters(CommandNumber itsCommandNumber, ProcPtr& fileFilter, TypeListHandle& typeList, short& dlgID, CPoint& where, ProcPtr& dlgHook, ProcPtr& modalFilter, Ptr& activeList, ProcPtr& activateProc, void*& yourDataPtr) { if (qNeedsAliasMgr || gConfiguration.hasAliasMgr) { dlgID = sfGetDialogID; where = CPoint(-1, -1); } else { dlgID = getDlgID; // getDlgID defined by Standard File DialogTHndl dlogTemplate = (DialogTHndl)(GetResource('DLOG', dlgID)); if (dlogTemplate) { CRect dialogRect = (*dlogTemplate)->boundsRect; CenterRectOnScreen(dialogRect, true, true, true); where = dialogRect[topLeft]; } else where = CPoint(100, 100); } this->GetFileTypeList(itsCommandNumber, typeList); fileFilter = NULL; dlgHook = NULL; modalFilter = (ProcPtr)gModalFilterYDProcPtr; activeList = NULL; activateProc = NULL; yourDataPtr = NULL; } // TApplication::GetStandardFileParameters //---------------------------------------------------------------------------------------- // TApplication::GetFileTypeList: //---------------------------------------------------------------------------------------- #pragma segment MAOpen void TApplication::GetFileTypeList(CommandNumber, TypeListHandle& typeList) { typeList = (TypeListHandle) NewPermHandle(4); (*typeList)[0] = fMainFileType; } // TApplication::GetFileTypeList //---------------------------------------------------------------------------------------- // TApplication::ShowError: //---------------------------------------------------------------------------------------- #pragma segment MAError void TApplication::ShowError(OSErr error, long message) { ErrorAlert(error, message); } // TApplication::ShowError //---------------------------------------------------------------------------------------- // TApplication::SpaceIsLowAlert: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::SpaceIsLowAlert() { #if !qPowerPC if (fEventLevel == 1) // Don't unload segs if nested event handling UnloadAllSegments(); #endif // Show 'space is low' alert only after ever fLowSpaceInterval ticks. if ((fLowSpaceInterval > 0) && this->IsFrontProcess()) { if (TickCount() > fNextSpaceMessage) { gInhibitNestedHandling = true; // Don't tell em again from the alert StdAlert(phSpaceIsLow); fNextSpaceMessage = TickCount() + fLowSpaceInterval; } } } // TApplication::SpaceIsLowAlert //---------------------------------------------------------------------------------------- // TApplication::DoSetCursor: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoSetCursor(CPoint globalMouse, RgnHandle cursorRegion) { this->GetDefaultCursorRegion(globalMouse, cursorRegion); SetCursor(&(qd.arrow)); } // TApplication::DoSetCursor //---------------------------------------------------------------------------------------- // TApplication::HandleCursor: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleCursor(CPoint globalMouse, RgnHandle cursorRegion) { WindowPtr aWMgrWindow; if (FindWindow(globalMouse, &aWMgrWindow) == inContent) { TWindow * cursorWindow = this->WMgrToWindow(aWMgrWindow); if ((cursorWindow) && cursorWindow->HandlesCursor()) { VPoint windowVPt(globalMouse); cursorWindow->SuperToLocal(windowVPt); cursorWindow->HandleCursor(windowVPt, fCursorRegion); // Convert cursor region from window coords to global coords cursorWindow->LocalToSuperRegion(cursorRegion); } } } // TApplication::HandleCursor //---------------------------------------------------------------------------------------- // TApplication::TrackCursor: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::TrackCursor(CPoint globalMouse) { #if qDebugMsg if (PtInRgn(globalMouse, fCursorRegion)) { if (gIntenseDebugging) fprintf(stderr, "cursor is in cursor region\n"); } #endif this->InvalidateCursorRgn(); // Find out if the cursor is in a window which handles the cursor, and if so, call // HandleCursor to allow a view to claim the cursor, and compute a region this->HandleCursor(*((CPoint *)&globalMouse), fCursorRegion); if (EmptyRgn(fCursorRegion)) this->DoSetCursor(globalMouse, fCursorRegion); // Make sure the cursorpoint is included PtAndRgn(globalMouse, fCursorRegion); #if qDebugMsg if (gIntenseDebugging) if (fCursorRegion == NULL) fprintf(stderr, "fCursorRegion is NULL\n"); #endif if (qDebug && gIntenseDebugging &&!PtInRgn(globalMouse, fCursorRegion)) { CRect bBox = (*fCursorRegion)->rgnBBox; fprintf(stderr, "Whoops, cursor region was not correctly calculated.\n"); fprintf(stderr, "global cursor = ", (char*)globalMouse); fprintf(stderr, " (*fCursorRegion)->rgnBBox = ", (char*) bBox); fprintf(stderr, "\n"); ProgramBreak("The cursor is not in the cursor region at end of TApplication.TrackCursor!"); } } // TApplication::TrackCursor //---------------------------------------------------------------------------------------- // TApplication::DoShowHelp: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::DoShowHelp(CPoint globalMouse, RgnHandle helpRegion) { if (HMIsBalloon()) { OSErr err = HMRemoveBalloon(); if (err != hmNoBalloonUp) FailOSErr(err); } this->GetDefaultHelpRegion(globalMouse, helpRegion); } // TApplication::DoShowHelp //---------------------------------------------------------------------------------------- // TApplication::HandleHelp: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::HandleHelp(CPoint globalMouse, RgnHandle helpRegion) { WindowPtr aWMgrWindow; if (FindWindow(globalMouse, &aWMgrWindow) == inContent) { TWindow * helpWindow = this->WMgrToWindow(aWMgrWindow); if ((helpWindow) && helpWindow->HandlesHelp()) { VPoint windowVPt(*((CPoint *)&globalMouse)); helpWindow->SuperToLocal(windowVPt); helpWindow->HandleHelp(windowVPt, helpRegion); // Convert helpRegion region from window coords to global coords helpWindow->LocalToSuperRegion(helpRegion); } } } // TApplication::HandleHelp //---------------------------------------------------------------------------------------- // TApplication::TrackHelp: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::TrackHelp(CPoint globalMouse) { #if qDebugMsg if (PtInRgn(globalMouse, fHelpRegion)) { if (gIntenseDebugging) fprintf(stderr, "cursor is in help region\n"); } #endif this->InvalidateHelpRgn(); // Find out if the cursor is in a window which handles help, and if so, call // HandleHelp to allow some subview to show help, and compute a region this->HandleHelp(*((CPoint *)&globalMouse), fHelpRegion); if (EmptyRgn(fHelpRegion)) this->DoShowHelp(globalMouse, fHelpRegion); // Make sure the cursorpoint is included PtAndRgn(globalMouse, fHelpRegion); #if qDebugMsg if (gIntenseDebugging) if (fHelpRegion == NULL) fprintf(stderr, "fHelpRegion is NULL\n"); #endif if (qDebug && gIntenseDebugging &&!PtInRgn(globalMouse, fHelpRegion)) { CRect bBox = (*fHelpRegion)->rgnBBox; fprintf(stderr, "Whoops, help region was not correctly calculated.\n"); fprintf(stderr, "global cursor = ", (char*)globalMouse); fprintf(stderr, " (*fHelpRegion)->rgnBBox = ", (char*) bBox); fprintf(stderr, "\n"); ProgramBreak("The cursor is not in the help region at end of TApplication.TrackHelp!"); } } // TApplication::TrackHelp //---------------------------------------------------------------------------------------- // TApplication::TrackMouse: //---------------------------------------------------------------------------------------- #pragma segment MADoCommand TTracker* TApplication::TrackMouse(const VPoint& theMouse, CPoint hysteresis, TTracker* theCommand) { TTracker* currentTracker = NULL; // so failure handler works VOLATILE(currentTracker); // so failure handler works VOLATILE(theCommand); // so failure handler works (theCommand is changed) FailInfo fi; Try(fi) { currentTracker = theCommand->HandleTrackBegin(theMouse, hysteresis); theCommand = NULL; // so failure handler works while (currentTracker && !currentTracker->IsDoneTracking()) if (this->IsFrontProcess()) currentTracker = currentTracker->HandleTrackContinue(); if (currentTracker) currentTracker = currentTracker->HandleTrackEnd(); fi.Success(); } else { if (theCommand) { theCommand->Completed(); if (theCommand->ShouldFreeOnCompletion()) { if (theCommand == theCommand->fContext->fLastCommand) theCommand->fContext->fLastCommand = NULL; // be sure to clear reference theCommand = (TTracker*) FreeIfObject(theCommand); } } if (currentTracker) { currentTracker->Completed(); if (currentTracker->ShouldFreeOnCompletion()) { if (currentTracker == currentTracker->fContext->fLastCommand) currentTracker->fContext->fLastCommand = NULL; // be sure to clear reference currentTracker = (TTracker*) FreeIfObject(currentTracker); } } fi.ReSignal(); } return currentTracker; } // TApplication::TrackMouse //---------------------------------------------------------------------------------------- // TApplication::UpdateAllWindows: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes void TApplication::UpdateAllWindows() { TToolboxEvent * event; ++fEventLevel; while ((event = this->GetEvent(updateMask + activMask, 0, NULL)) != NULL) event->Process(); --fEventLevel; } // TApplication::UpdateAllWindows //---------------------------------------------------------------------------------------- // TApplication::DoMakeViewServer: //---------------------------------------------------------------------------------------- #pragma segment MAInit void TApplication::DoMakeViewServer() { TViewServer * aViewServer = new TViewServer; aViewServer->IViewServer(); // assigns the global reference } // TApplication::DoMakeViewServer //---------------------------------------------------------------------------------------- // TApplication::WMgrToWindow: //---------------------------------------------------------------------------------------- #pragma segment MAApplicationRes TWindow* TApplication::WMgrToWindow(WindowPtr aWindowPtr) { // just uses the global routine in UWindow return ::WMgrToWindow(aWindowPtr); } // TApplication::WMgrToWindow //---------------------------------------------------------------------------------------- // TApplication::GetApplicationName: //---------------------------------------------------------------------------------------- #pragma segment MAWriteFile void TApplication::GetApplicationName(CStr255& theName) { if (qNeedsProcessMgr || gConfiguration.hasProcessMgr) { FailInfo fi; Try(fi) { ProcessInfoRec info; info.processInfoLength = sizeof(ProcessInfoRec); info.processName = theName; info.processAppSpec = NULL; FailOSErr(GetProcessInformation(&fProcessNumber, &info)); fi.Success(); } else { #if qDebug ProgramBreak("TApplication::GetApplicationName() failed!"); #endif // no need to fail completely, just return generic string theName = "<Application>"; } } else { theName = LMGetCurApName(); } } // TApplication::GetApplicationName